Skip to content

Commit

Permalink
Add code quality workflow and update composer.json. Also add data-cho…
Browse files Browse the repository at this point in the history
…rd attribute.
  • Loading branch information
intelektron committed Jan 15, 2024
1 parent e40e3bc commit cb7ac26
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 26 deletions.
45 changes: 45 additions & 0 deletions .github/workflows/codequality.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: PHP Composer

on:
push:
branches: [ "master", "develop" ]
pull_request:
branches: [ "master", "develop" ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Validate composer.json and composer.lock
run: composer validate --strict

- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v3
with:
path: vendor
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-php-
- name: Install dependencies
run: composer install --prefer-dist --no-progress

- name: Run test suite
run: composer run-script test

- name: Run phpcs
run: composer run-script cs

- name: Run phpstan
run: composer run-script phpstan

- name: Run php-compatibility
run: composer run-script php-compatibility
49 changes: 28 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
# The chordpro-php library
# The chordpro-php library 🎸

A simple tool to parse, transpose & format [ChordPro](https://www.chordpro.org) songs with lyrics & chords.

Forked from <https://github.com/nicolaswurtz/chordpro-php> by [Nicolaz Wurtz](https://github.com/nicolaswurtz), on LGPL-3 license.
_Forked from <https://github.com/nicolaswurtz/chordpro-php> by [Nicolaz Wurtz](https://github.com/nicolaswurtz), on LGPL-3 license._

The following output formats are currently supported
The following output formats are currently supported:

- HTML (verses contain blocks with embedded `span` for aligning chords with lyrics)
- JSON (verses are arrays of chords and lyrics for alignment purposes)
- Plain text (chords are aligned with monospace text thanks to whitespace)
- **HTML** (verses contain blocks with embedded `span` for aligning chords with lyrics).
- **JSON** (verses are arrays of chords and lyrics for alignment purposes).
- **Plain text** (chords are aligned with monospace text thanks to whitespace).

And provides some extra functionality:
The library provides some extra functionality:

- Tranpose chords by semitones or to the target key.
- Parse and display various chord notations:
- French (`Do`, ``, `Mi`)
- German (`Fis`, `a`)
- With UTF characters (`A♭`, `F♯`)
- French (`Do`, ``, `Mi`).
- German (`Fis`, `a`).
- With UTF characters (`A♭`, `F♯`).
- Guess the key of a song.

## Install
## Installation

Via composer:

Expand All @@ -29,17 +29,19 @@ composer require intelektron/chordpro-php

## Usage

See `web/example.php` for demo with CSS styling.
See [web/example.php] for demo with CSS styling.

``` php
<?php

require __DIR__ . '/vendor/autoload.php';

$txt = "{t:ChordpropPHP Song}
$txt = "{t:Chordpro-PHP Song}
{st:Nicolas Wurtz}
{c:GPL3 2019 Nicolas Wurtz}
{key:C}

# Let's start it!
[C]This is the [Dm]beautiful [Em]song
I [Dm]wrote in [F/G]Chordpro for[C]mat [Dm/F]
Let's sing it a[C/E]long
Expand All @@ -51,7 +53,8 @@ Let's sing it a[C/E]long
{eoc}

{c:Final}
[Em/D]This is the [Bb]end.";
[Em/D]This is the [Bb]end.
";

$parser = new ChordPro\Parser();

Expand All @@ -67,7 +70,7 @@ $song = $parser->parse($txt);
$transposer = new ChordPro\Transposer();

// Define how many semitones you want to transpose by.
$transposer->transpose($song,-5);
$transposer->transpose($song, -5);

// If the song key is known, you can also transpose from key to key.
// $transposer->transpose($song,'Abm');
Expand Down Expand Up @@ -100,7 +103,7 @@ Simply give an array with values at true or false for each key/option.
The key can be set/changed in the following ways:

- Manually, by calling `$song->setKey('A')`.
- By parsing a song with metadata, e.g. `{key:A}`
- By parsing a song with metadata, e.g. `{key:A}`.
- By transposing the song to another key.

You can get the key by calling:
Expand All @@ -117,7 +120,7 @@ $key = $guess->guessKey($song);

## Chord notations

The library supports several chord notations. You can also create your own (by implementing `ChordNotationInterface`). Notations are used for both parsing and formatting. So you can parse a song in German notation and display it as French:
The library supports several chord notations. You can also create your own (by implementing [src/Notation/ChordNotationInterface.php]). Notations are used for both parsing and formatting. So you can parse a song in German notation and display it as French:

```php
$txt = 'A typical [fis]German [a]verse';
Expand All @@ -126,7 +129,7 @@ $notation = new ChordPro\Notation\GermanChordNotation();
$song = $parser->parse($song, [$notation])
```

At this point, `fis` is recognized and saved as `F#m`, and `a` is saved as `Am`. Note that you can pass multiple notations to the parser, in order of precedence. This can be useful if you have mixed up chord notations in one song.
At this point, `fis` is recognized and saved internally as `F#m`, and `a` is saved as `Am`. Note that you can pass multiple notations to the parser, in order of precedence. This can be useful if you have mixed up chord notations in one song.

Now, to show this song in French:

Expand All @@ -140,27 +143,31 @@ $html = $monospaceFormatter->format($song, [
// A typical German verse
```

The `UtfChordFormatter` provides a nice-looking chords with `` and `` symbols instead of ASCII characters.

## Styling the HTML code

### Song lines

Lines are made up of blocks. Each block consists of a text and a chord. The chord has the class `chordpro-chord' and the text has the class `chordpro-text'.
Lines are made up of blocks. Each block consists of a text and a chord. The chord has the class `chordpro-chord` and the text has the class `chordpro-text`.

A typical line of the song looks like this:

```html
<div class="chordpro-line">
<span class="chordpro-block">
<span class="chordpro-chord">C</span>
<span class="chordpro-chord" data-chord="C">C</span>
<span class="chordpro-text">This is the </span>
</span>
<span class="chordpro-block">
<span class="chordpro-block" data-chord="Dm">
<span class="chordpro-chord">Dm</span>
<span class="chordpro-text">beautiful song</span>
</span>
</div>
```

The `data-chord` attribute stores an English representation of the chord, regardless of the output notation.

### Song sections

The ChordPro format allows to organize your songs into sections. The following song fragment:
Expand Down
13 changes: 13 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,19 @@
"email": "[email protected]"
}
],
"scripts": {
"test": "phpunit tests",
"phpstan": "phpstan analyse",
"php-compatibility": "phpcs --standard=phpcs.xml",
"cs": "php-cs-fixer fix --config=.php-cs-fixer.php --dry-run --diff",
"cs-fix": "php-cs-fixer fix --config=.php-cs-fixer.php",
"check": [
"@test",
"@phpstan",
"@php-compatibility",
"@cs"
]
},
"config": {
"allow-plugins": {
"phpstan/extension-installer": true
Expand Down
9 changes: 7 additions & 2 deletions src/Formatter/HtmlFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,26 +73,31 @@ private function getLyricsHtml(Lyrics $lyrics): string
$line = '<div class="chordpro-line">'."\n";
foreach ($lyrics->getBlocks() as $block) {

$originalChords = [];
$chords = [];

$slicedChords = $block->getChords();
foreach ($slicedChords as $slicedChord) {
if ($slicedChord->isKnown()) {
$ext = $slicedChord->getExt();
$ext = $slicedChord->getExt($this->notation);
if ($ext !== '') {
$ext = '<sup>'.$ext.'</sup>';
}

$chords[] = $slicedChord->getRootChord($this->notation).$ext;
$originalChords[] = $slicedChord->getRootChord().$slicedChord->getExt();
} else {
$chords[] = $slicedChord->getOriginalName();
$originalChords[] = $slicedChord->getOriginalName();
}
}

$chord = implode('/', $chords);
$originalChord = implode('/', $originalChords);
$text = $this->blankChars($block->getText());

$line .= '<span class="chordpro-block">' .
'<span class="chordpro-chord">'.$chord.'</span>' .
'<span class="chordpro-chord" data-chord="'.$originalChord.'">'.$chord.'</span>' .
'<span class="chordpro-text">'.$text.'</span>' .
'</span>';
}
Expand Down
6 changes: 5 additions & 1 deletion src/Formatter/JSONFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,18 +69,22 @@ private function getLyricsJSON(Lyrics $lyrics): array
$return = [];
foreach ($lyrics->getBlocks() as $block) {
$chords = [];
$originalChords = [];
$slicedChords = $block->getChords();
foreach ($slicedChords as $slicedChord) {
if ($slicedChord->isKnown()) {
$chords[] = $slicedChord->getRootChord($this->notation).$slicedChord->getExt($this->notation);
$originalChords[] = $slicedChord->getRootChord().$slicedChord->getExt();
} else {
$chords[] = $slicedChord->getOriginalName();
$originalChords[] = $slicedChord->getOriginalName();
}
}
$chord = implode('/', $chords).' ';
$originalChord = implode('/', $originalChords).' ';

$text = $block->getText();
$return[] = ['chord' => trim($chord), 'text' => $text];
$return[] = ['chord' => trim($chord), 'text' => $text, 'originalChord' => trim($originalChord)];
}
return [
'type' => 'line',
Expand Down
4 changes: 2 additions & 2 deletions tests/Formatter/HtmlFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public function testWithChords(): void
'<br />' . "\n" .
'<div class="chordpro-verse">' . "\n" .
'<div class="chordpro-line">' . "\n" .
'<span class="chordpro-block"><span class="chordpro-chord">C<sup>7</sup></span><span class="chordpro-text">Test&nbsp;</span></span><span class="chordpro-block"><span class="chordpro-chord">D</span><span class="chordpro-text">Test2</span></span>' . "\n" .
'<span class="chordpro-block"><span class="chordpro-chord" data-chord="C7">C<sup>7</sup></span><span class="chordpro-text">Test&nbsp;</span></span><span class="chordpro-block"><span class="chordpro-chord" data-chord="D">D</span><span class="chordpro-text">Test2</span></span>' . "\n" .
'</div>' . "\n" .
'</div>' . "\n";

Expand Down Expand Up @@ -61,7 +61,7 @@ public function testWithoutMetadata(): void
$expected = '<br />' . "\n" .
'<div class="chordpro-verse">' . "\n" .
'<div class="chordpro-line">' . "\n" .
'<span class="chordpro-block"><span class="chordpro-chord">C<sup>7</sup></span><span class="chordpro-text">Test&nbsp;</span></span><span class="chordpro-block"><span class="chordpro-chord">D</span><span class="chordpro-text">Test2</span></span>' . "\n" .
'<span class="chordpro-block"><span class="chordpro-chord" data-chord="C7">C<sup>7</sup></span><span class="chordpro-text">Test&nbsp;</span></span><span class="chordpro-block"><span class="chordpro-chord" data-chord="D">D</span><span class="chordpro-text">Test2</span></span>' . "\n" .
'</div>' . "\n" .
'</div>' . "\n";

Expand Down

0 comments on commit cb7ac26

Please sign in to comment.