App-Music-ChordPro

 view release on metacpan or  search on metacpan

lib/ChordPro.pm  view on Meta::CPAN


=item B<--start-page-number=>I<N> (short: B<-p>)

Sets the starting page number for the output.

=item B<--strict>

Requires the input to be strictly compliant to the ChordPro standard.

This is enabled by default. See also B<--nostrict>.

=item B<--subtitle=>I<XXX>

Subtitle (for songbooks).

=item B<--title=>I<XXX>

Title (for songbooks).

If specified and a table of contents is requested, a nice coverpage
will be added.

Note that B<--title> overrides B<--cover>.

=item B<--toc> (short: B<-i>)

Includes a table of contents.

By default a table of contents is included in the PDF output when
it contains more than one song.

=item B<--transpose=>I<XX> (short: -x)

I<XX> must be a number in the range -24 .. +24, optionally followed by
one of C<s>, or C<f>.

Transposes all songs by the given number of semi-tones.
A positive number transposes up, a negative number transposes down.

If the resultant key requires accidentals the postfix controls whether
sharps or flats are used. See the docs.

=item B<--version> (short: B<-V>)

Prints the program version and exits.

=back

=head2 Chordii compatibility options

The following Chordii command line options are recognized. Note that
not all of them actually do something.

Options marked with * are better specified in the config file.

B<Note:> Chordii used the term _grid_ for chord diagrams. It
should not be confused with ChordPro grids.

=over 4

=item B<--text-font=>I<FONT> (short: B<-T>) *

Sets the font used to print lyrics and comments.

I<FONT> can be either a full path name to a TrueType font file, or the
name of one of the standard fonts. See section L</FONTS> for more
details.

=item B<--text-size=>I<N> (short: B<-t>) *

Sets the font size for lyrics and comments.

=item B<--chord-font=>I<FONT> (short: B<-C>) *

Sets the font used to print the chord names.

I<FONT> can be either a full path name to a TrueType font file, or the
name of one of the standard fonts. See section L</FONTS> for more
details.

=item B<--chord-size=>I<N> (short: B<-c>) *

Sets the font size for the chord names.

=item B<--chord-grid-size=>I<N> (short: B<-s>) *

Sets the total width of a chord diagram.

=item B<--chord-grids>

Prints chord diagrams of all chords used in a song.

=item B<--no-chord-grids> (short: B<-G>) *

Disables printing of chord diagrams of the chords used in a song.

=item B<--easy-chord-grids>

Not supported.

=item B<--no-easy-chord-grids> (short: B<-g>)

Not supported.

=item B<--chord-grids-sorted> (short: B<-S>) *

Prints chord diagrams of the chords used in a song, ordered by key and
type.

=item B<--no-chord-grids-sorted> *

Prints chord diagrams in the order they appear in the song.

=item B<--user-chord-grids> *

Prints chord diagrams of all user defined chords used in a song.

=item B<--even-pages-number-left> (short B<-L>)

Not supported. Use C<pdf.even-odd-pages> in the config instead.

=item B<--odd-pages-number-left>

Not supported. Use C<pdf.even-odd-pages> in the config instead.

=item B<--page-size=>I<FMT> (short: B<-P>) *

Specifies the page size for the PDF output, e.g. C<a4> (default), C<letter>.

=item B<--single-space> (short B<-a>)) *

When a lyrics line has no chords associated, suppresses the vertical
space normally occupied by the chords.

=item B<--vertical-space=>I<N> (short: B<-w>) *

Adds some extra vertical space between the lines.

=item B<--2-up> (short: B<-2>)

Not supported.

=item B<--4-up> (short: B<-4>)

Not supported.

=item B<--page-number-logical> (short: B<-n>)

Not supported.

=item B<--dump-chords> (short: B<-D>)

Dumps a list of built-in chords in a form dependent of the backend used.
The PDF backend will produce neat pages of chord diagrams.
The ChordPro backend will produce a list of C<define> directives.

=item B<--dump-chords-text> (short: B<-d>)

Dumps a list of built-in chords in the form of C<define> directives,
and exits.

=back

=head2 Configuration options

See L<ChordPro::Config> for details about the configuration
files.

Note that missing default configuration files are silently ignored.
Also, B<chordpro> will never create nor write configuration files.

=over

=item B<--nosongconfig>

Don't use song specific config files, even if they exist.

=item B<--sysconfig=>I<CFG>

Designates a system specific config file.

The default system config file depends on the operating system and user
environment. A common value is C</etc/chordpro.json> on Linux systems.

This is the place where the system manager can put settings like the
paper size, assuming that all printers use the same size.

=item B<--nosysconfig>

Don't use the system specific config file, even if it exists.

=item B<--userconfig=>I<CFG>

Designates the config file for the user.

The default user config file depends on the operating system and user
environment. Common values are C<$HOME/.config/chordpro/chordpro.json>
and C<$HOME/.chordpro/chordpro.json>, where C<$HOME> indicates the
user home directory.

Here you can put settings for your preferred fonts and other layout
parameters that you want to apply to all B<chordpro> runs.

=item B<--nouserconfig>

Don't use the user specific config file, even if it exists.

=item B<--config=>I<CFG> (shorter: B<--cfg>)

Designates the config file specific for this run.

Default is a file named C<chordpro.json> in the current directory.

Here you can put settings that apply to the files in this
directory only.

You can specify multiple config files. The settings are accumulated.

=item B<--noconfig>

Don't use the specific config file, even if it exists.

=item B<--define=>I<item>

Sets a configuration item. I<item> must be in the format of
colon-separated configuration keys, an equal sign, and the value. For
example, the equivalent of B<--diagrams=none> is
B<--define=diagrams.show=0>.

B<--define> may be used multiple times to set multiple items.

=item B<--no-default-configs> (short: B<-X>)

Do not use any config files except the ones mentioned explicitly on
the command line.

This guarantees that the program is running with the default
configuration.

=item B<--print-template-config>

Prints a simplified template configuration to standard output, and
exits. The configuration is commented to explain its contents.

The config contains most of the ChordPro configuration items, all
commented out. It is easy to get started with configuring ChordPro
by enabling and modifyng just a few items at a time.

=item B<--print-default-config>

If used once, behaves like `--print-template-config`. This is to avoid
confusing novice users.

To get the full default configuration, repeat this option.

=item B<--print-final-config>

Prints the final configuration (after processing all system, user and
other config files)  to standard output, and exits.

=item B<--convert-config=>I<file>

lib/ChordPro.pm  view on Meta::CPAN


       ### NON-CLI OPTIONS ###

       'chords-column'  => 0,           # chords in a separate column

       # Development options (not shown with -help).
       debug            => 0,           # debugging
       trace            => 0,           # trace (show process)

       # Service.
       _package         => $my_package,
       _name            => $my_name,
       _version         => $my_version,
       _stdin           => \*STDIN,
       _stdout          => \*STDOUT,
       _stderr          => \*STDERR,
       _argv            => [ @ARGV ],
      };

    # Colled command line options in a hash, for they will be needed
    # later.
    my $clo = {};

    # When running in reference mode, we carefully defeat everything
    # the user could change to the built-in default config.
    my $reference = 0;

    # Sorry, layout is a bit ugly...
    my $ok =
      GetOptions
         ($clo,

          ### Options ###

	  "a2crd!",			# perform ascii to cho
	  "crd",			# input is ascii, not cho
          "output|o=s",                 # Saves the output to FILE
          "generate=s",
          "backend-option|bo=s\%",
	  "diagrams=s",			# Prints chord diagrams
          "encoding=s",
	  "csv!",			# Generates contents CSV
	  "front-matter=s",		# Front matter page(s)
	  "cover=s",			# Cover page(s)
	  "back-matter|back=s",		# Back matter page(s)
	  "filelist=s@",		# List of input files
	  "title=s",			# Title (for books)
	  "subtitle=s",			# Subtitle (for books)
	  "meta=s\%",			# Command line meta data
	  "decapo",			# remove capo
	  "fragment|F",			# partial (incomplete) song
	  "strict!",			# strict conformance

	  ### Experimental ###

	  "progress_callback=s",

	  ### Standard Chordii Options ###

          "about|A+" => \$about,        # About...
          "chord-font|C=s",             # Sets chord font
          "chord-grid-size|s=f",        # Sets chord diagram size [30]
          "chord-grids-sorted|S!",      # Prints chord diagrams ordered
          "chord-size|c=i",             # Sets chord size [9]
          "dump-chords|D",              # Dumps chords definitions (PostScript)
          "dump-chords-text|d" => \$dump_chords,  # Dumps chords definitions (Text)
          "dump-chords-json" => sub { $dump_chords = 2},  # Dumps instrument defs (json).
          "even-pages-number-left|L",   # Even pages numbers on left
          "odd-pages-number-left",      # Odd pages numbers on left
          "lyrics-only|l",              # Only prints lyrics
          "G" => sub { $clo->{'chord-grids'} = 0 },
          "chord-grids!",               # En[dis]ables printing of chord diagrams
          "easy-chord-grids|g!",        # Do[esn't] print diagrams for built-in "easy" chords. Ignored.
          "page-number-logical|n",      # Numbers logical pages, not physical
          "page-size|P=s",              # Specifies page size [letter, a4 (default)]
          "single-space|a!",            # Automatic single space lines without chords
          "start-page-number|p=i",      # Starting page number [1]
          "text-size|t=i",              # Sets text size [12]
          "text-font|T=s",              # Sets text font
          "i" => sub { $clo->{toc} = 1 },
          "toc!",                       # Generates a table of contents
          "transpose|x=s",              # Transposes by N semi-tones
          "transcode|xc=s",             # Transcodes to another notation
          "user-chord-grids!",          # Do[esn't] print diagrams for user defined chords.
          "version|V" => \$version,     # Prints version and exits
          "vertical-space|w=f",         # Extra vertical space between lines
          "2-up|2",                     # 2 pages per sheet
          "4-up|4",                     # 4 pages per sheet

          ### Configuration handling ###

          'config|cfg=s@',
          'noconfig|no-config',
          'sysconfig=s',
          'nosysconfig|no-sysconfig',
          'nolegacyconfig|no-legacyconfig',	# legacy
          'userconfig=s',
          'nosongconfig|no-songconfig',
          'nouserconfig|no-userconfig',
	  'nodefaultconfigs|no-default-configs|X',
	  'define=s%',
	  'print-default-config+' => \$defcfg,
	  'print-final-config'    => \$fincfg,
	  'print-delta-config'    => \$deltacfg,
	  'print-template-config' => \$tmplcfg,
	  'convert-config=s',

	  # This aborts option scanning.
	  'reference|R'		 => sub { $reference++;
					  CORE::die("!FINISH!"); },

          ### Standard options ###

          'ident'               => \$ident,
          'help|h|?'            => \$help,
          'help-config'         => sub { $manual = 2 },
          'manual'              => \$manual,
          'verbose|v+',
	  I			=> sub { $clo->{progress_callback} = "warn" },
          'trace',
          'debug+',

         );

    # If --reference was encountered, retry with a very restricted set
    # of options.
    if ( $reference ) {
	@ARGV = @{ $options->{_argv} };
	warn("Running in reference mode.\n");
	$ok =
	  GetOptions
	  ($clo,

	  ### Options for reference run ###

	  "output|o=s",                 # Saves the output to FILE
	  "strict!",			# strict conformance
          "about|A" => \$about,         # About...
          "version|V" => \$version,     # Prints version and exits

lib/ChordPro.pm  view on Meta::CPAN

    }
    exit $exit if defined $exit;
}

use List::Util qw(uniq);

sub ::runtimeinfo {
    my $level = shift // "normal";
    my %i = %{runtime_info($level)};
    my $fmt0   = "  %-26.26s %-10s";
    my $fmt2   = $fmt0 . "\n";
    my $fmt3   = $fmt0 . " (%s)\n";

    my $msg;
    for ( $i{general}->{chordpro} ) {
	if ( $_->{aux} ) {
	    $msg = sprintf( $fmt3,
			    "ChordPro " . ($_->{type}//"core"), $_->{version},
			    $_->{aux} );
	}
	else {
	    $msg = sprintf( $fmt2,
			    "ChordPro " . ($_->{type}//"core"), $_->{version} );
	}
    }
    if ( $level eq "short" ) {	# used for PDF Creator info
	$msg =~ s/^\s+//;
	$msg =~ s/\s+/ /g;
	$msg =~ s/\n+$//;
	return $msg;
    }

    for ( $i{general}{perl} ) {
	$msg .= sprintf( $fmt3, "Perl", $_->{version}, $_->{dppath} );
    }

    for ( $i{general}{packager} ) {
	next unless defined;
	$msg .= sprintf( $fmt2, $_->{packager}." Packager", $_->{version} );
    }

    # Determine resource path.
    my @p;
    my $tag = "CHORDPRO_LIB";
    for ( @{$i{general}{library}} ) {
	$msg .= sprintf( $fmt2, $tag, $_->{dppath} );
	$tag = "";
    }
    for ( $i{general}{xdg_home} ) {
	next unless defined;
	$msg .= sprintf( $fmt2, "XDG_CONFIG_HOME", $_->{dppath} );
    }

    $tag = "Resource path";
    for ( @{$i{resources}} ) {
	$msg .= sprintf( $fmt2, $tag, $_->{dppath} );
	$tag = "";
    }

    $tag = "FONTDIR";
    for ( @{$i{general}{fontdir}//[]} ) {
	next unless defined;
	$msg .= sprintf( $fmt2, $tag, $_->{dppath} );
	$tag = "";
    }

    for ( $i{general}{abc} ) {
	next unless defined;
	$msg .= sprintf( $fmt2, "ABC support", $_ );
    }

    $msg .= "\nModules and libraries:\n";
    for ( @{$i{modules}} ) {
	if ( $level eq "normal" ) {
	    $msg .= sprintf( $fmt2, $_->{name}, $_->{version} );
	}
	else {
	    if ( defined $_->{dppath} ) {
		$msg .= sprintf( $fmt3, $_->{name}, $_->{version}, $_->{dppath} );
	    }
	    else {
		$msg .= sprintf( $fmt2, $_->{name}, $_->{version} );
	    }
	}
	if ( $_->{library} ) {
	    if ( $_->{library} =~ /i$/ ) {
		$msg .= sprintf( $fmt3, "  library", $_->{library}, "embedded" );
	    }
	    else {
		$msg .= sprintf( $fmt2, "  library", $_->{library} );
	    }
	}
    }

    return $msg;
}

# Gather runtime details.
sub runtime_info {
    my $level = shift // "normal";
    my $cp = ChordPro::Paths->get;
    my $res;

    # Sometimes version numbers are localized...
    my $dd = sub { my $v = $_[0]; $v =~ s/,/./g; $v };

    for ( $res->{general}{chordpro} ) {
	$_->{version} = $dd->($VERSION);
	$_->{type} = $::options->{reference} ? "reference" : "core";
	$_->{aux} = "Unsupported development snapshot"
	  if $VERSION =~ /_/;
    }
    return $res if $level eq "short";

    $res->{general}{perl} =
      { version => "$^V",
	path    => $^X,
	dppath  => $cp->display($^X),
      };

    $res->{general}{packager} =
      { packager => CP->packager,
	version  => CP->packager_version,
      } if CP->packager;

    # Determine resource path.
    $res->{general}{library} = [];
    if ( defined $ENV{CHORDPRO_LIB} ) {
	for ( $cp->path($ENV{CHORDPRO_LIB}) ) {
	    push( @{$res->{general}{library}},
		  { path   => $_,
		    dppath => $cp->display($_) } );
	}
    }

    if ( defined $ENV{FONTDIR} ) {
	for ( $cp->path($ENV{FONTDIR}) ) {
	    push( @{$res->{general}{fontdir}},
		  { path   => $_,
		    dppath => $cp->display($_) } );
	}
    }

    $res->{resources} =
      [ map { { path => $_, dppath => $cp->display($_) } }
	    uniq( @{ $cp->resdirs } ) ];

    eval {
	require ChordPro::Delegate::ABC;
	my $x = ChordPro::Delegate::ABC->info();
	$res->{general}{abc} = $x->{info} if $x->{info};
	1;
    } or $@ =~ /Can't locate/ or warn($@);

    my @p;

    my $vv = sub {
	my ( $mod ) = @_;
	no strict 'refs';
	my $pm = $mod =~ s;::;/;gr . ".pm";
	my $loc = $INC{$pm};
	push( @p, { name    => $mod,
		    version => "".$dd->(${${"${mod}::"}{VERSION}}),
		    path    => $loc,
		    dppath  => $loc =~ /^(.*)\/\Q$pm\E$/ ? $cp->display($1) : $loc,
		  } );
    };

    local $SIG{__WARN__} = sub {};
    local $SIG{__DIE__} = sub {};
    eval {
	require Wx;
	no strict 'subs';
	push( @p,
	      { name => "wxPerl",    version => $dd->($Wx::VERSION)  },
	      { name => "wxWidgets", version => $dd->($Wx::wxVERSION) } );
    } if $ENV{DISPLAY};

    $vv->("Storable");
    $vv->("Object::Pad");
    eval {
	require Text::Layout;
	$vv->("Text::Layout");
    };
    eval {
	require HarfBuzz::Shaper;
	$vv->("HarfBuzz::Shaper");
	$p[-1]->{library} = $dd->(HarfBuzz::Shaper::hb_version_string());
    };
    eval {
	require String::Interpolate::Named;
	$vv->("String::Interpolate::Named");
    };
    eval {
	require File::LoadLines;
	$vv->("File::LoadLines");
    };
    eval {

lib/ChordPro.pm  view on Meta::CPAN

    return split( /;/, $path );
}

sub app_usage {
    my ($fh, $exit) = @_;
    my %cfg;
    for ( qw( config userconfig sysconfig) ) {
	$cfg{$_} = $configs{$_} || "no default";
    }

    if ( $::options->{reference} ) {
	print ${fh} <<EndOfUsage;
Usage: $0 [ options ] [ file ... ]

Options:
    --[no]strict        Strict conformance
    --output=FILE  -o   Saves the output to FILE
    --about  -A         About ChordPro...
    --version  -V       Prints version and exits
    --help  -h          This message
    --ident             Show identification
    --verbose           Verbose information. Repeat for more.
EndOfUsage
	exit $exit if defined $exit;
	return;
    }

    ####TODO: weed out for --reference.
    print ${fh} <<EndOfUsage;
Usage: $0 [ options ] [ file ... ]

Options:
    --a2crd                       Perform text to ChordPro conversion only
    --noa2crd                     Do not auto-sense text to ChordPro conversion
    --about  -A                   About ChordPro...
    --back-matter=FILE            Add back matter pages from PDF document
    --config=JSON  --cfg          Config definitions (multiple)
    --cover=FILE                  Add cover pages from PDF document
    --crd                         Input is text, not ChordPro
    --csv                         (with PDF) Also generate CSV
    --decapo                      Eliminate capo settings
    --diagrams=WHICH		  Prints chord diagrams
    --encoding=ENC                Encoding for input files (UTF-8)
    --filelist=FILE               Reads song file names from FILE
    --fragment -F                 Partial (incomplete) song
    --front-matter=FILE           Add front matter pages from PDF document
    --lyrics-only  -l             Only prints lyrics
    --meta KEY=VALUE              Add meta data
    --output=FILE  -o             Saves the output to FILE
    --[no]strict                  Strict conformance
    --start-page-number=N  -p     Starting page number [1]
    --subtitle=VALUE		  Use with --title for a nice subtitle.
    --title=VALUE		  Adds a nice cover page using this title.
    --toc --notoc -i              Generates/suppresses a table of contents
    --transcode=SYS  -xc          Transcodes to notation system
    --transpose=N  -x             Transposes by N semi-tones
    --version  -V                 Prints version and exits

Chordii compatibility.
Options marked with * are better handled in the config file.
    --chord-font=FONT  -C         *Sets chord font
    --chord-grid-size=N  -s       *Sets chord diagram size [30]
    --chord-grids-sorted  -S      *Prints chord diagrams ordered by key
    --chord-size=N  -c            *Sets chord size [9]
    --dump-chords  -D             Dumps chords definitions (PDF)
    --dump-chords-text  -d        Dumps chords definitions (Text)
    --even-pages-number-left  -L  *Not supported
    --odd-pages-number-left       *Not supported.
    --no-chord-grids  -G          *Disables printing of chord diagrams
    --no-easy-chord-grids  -g     Not supported
    --page-number-logical  -n     Not supported
    --page-size=FMT  -P           *Specifies page size [letter, a4 (default)]
    --single-space  -a            *Automatic single space lines without chords
    --text-size=N  -t             *Sets text size [12]
    --text-font=FONT  -T          *Sets text font
    --user-chord-grids		  *Prints the user defined chords in the song
    --vertical-space=N  -w        *Extra vertical space between lines
    --2-up  -2                    Not supported
    --4-up  -4                    Not supported

Configuration options:
    --config=CFG        Project specific config file ($cfg{config})
    --define=XXX=YYY	Sets config item XXX to value YYY
    --noconfig          Don't use a project specific config file
    --nodefaultconfigs  -X  Don't use any default config files
    --nosongconfig      Don't use song specific configs
    --nosysconfig       Don't use a system specific config file
    --nouserconfig      Don't use a user specific config file
    --print-default-config   Prints the default config and exits
    --print-delta-config   Prints the diffs for the resultant config and exits
    --print-final-config   Prints the resultant config and exits
    --reference  -R     Reference mode (no configs etc.)
    --sysconfig=CFG     System specific config file ($cfg{sysconfig})
    --userconfig=CFG    User specific config file ($cfg{userconfig})
Missing default configuration files are silently ignored.

Miscellaneous options:
    --help  -h          This message
    --help-config       Help for ChordPro configuration
    --ident             Show identification
    --manual            The full manual.
    --verbose           Verbose information. Repeat for more.
EndOfUsage
    exit $exit if defined $exit;
}

=head1 FONTS

There are two ways to specify fonts: with a font filename, and a
built-in font name.

A font filename must be either and absolute filename, or a relative
filename which is interpreted relative to the I<font path>, which
consists of configuration setting C<fontdir>, the C<fonts> resource
dir, and the contents of environment variable C<FONTDIR>. In any case,
the filename should point to a valid TrueType (C<.ttf>) or OpenType
(C<.otf>) font.

If it is not a filename, it must be the name one of the built-in PDF core fonts:

  Courier                             Symbol
  Courier-Bold                        Times-Bold
  Courier-BoldOblique                 Times-BoldItalic
  Courier-Oblique                     Times-Italic
  Helvetica                           Times-Roman
  Helvetica-Bold                      ZapfDingbats
  Helvetica-BoldOblique
  Helvetica-Oblique

=head1 MOTIVATION

Why a rewrite of Chordii?

Chordii is the de facto reference implementation of the ChordPro file
format standard. It implements ChordPro version 4.

ChordPro version 5 adds a number of new features, and this was pushing
the limits of the very old program. Unicode support would have been
very hard to add, and the whole program centered around PostScript
generation, while nowadays PDF would be a much better alternative.

So I decided to create a new reference implementation from the ground
up. I chose a programming language that is flexible and very good at
handling Unicode data. And that is fun to program in.

=head1 CURRENT STATUS

This program implements ChordPro version 5. It
supports most of the features of Chordii, and a lot more:

* Native PDF generation

* Unicode support (all input is UTF8)

* User defined chords and tuning, not limited to 6 strings.

* Support for Nashville Numbering and Roman Numbering.

* Support for external TrueType and OpenType fonts

* Font kerning (with external TrueType fonts)

* Fully customizable layout, fonts and sizes

* Customizable backends for PDF, ChordPro, LilyPond*, LaTeX* and HTML*.

(* = under development)

=head1 AUTHOR

Johan Vromans C<< <jv at CPAN dot org > >>

=head1 SUPPORT

ChordPro (the program) development is hosted on GitHub, repository
L<https://github.com/ChordPro/chordpro>.

Please report any bugs or feature requests to the GitHub issue tracker,
L<https://github.com/ChordPro/chordpro/issues>.

A user community discussing ChordPro can be found at
L<https://groups.google.com/forum/#!forum/chordpro>.

=head1 LICENSE

Copyright (C) 2010,2018 Johan Vromans,

This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.

=cut

1;



( run in 0.862 second using v1.01-cache-2.11-cpan-5735350b133 )