Generating the opus

In case of classical music, all my 'albums' are compositions.
It would be nice to have a list of all works by opus number.


Expressions can be used to parse the album title and extract the opus number.

Most albums have a title like:

 

Bach: Cello Sonata No. 2 in D-dur, BWV 1028

 

You can use a MID function to retrieve a part of a string
MID([Album],start,length) would do the job.

How to find the starting position of BWV?
Normally you have 'find' function returning the position e.g. Find([Album],'BWV') but this is not available in JRMC.
Now way to combine the MID with a lookup function.

ListItem

This function makes a list of a string given a delimiting character.
Each item of this list has an index starting at 0
           
ListItem([Album],0,BWV)=Bach: Cello Sonata No. 2 in D-dur,
ListItem([Album],1,BWV)=1028

Obvious the delimiter is not part of the list.

I want to have the BWV in front

BWV ListItem([Album],1,BWV)=BWV 1028

However when the BWV is not available the column is filled with BWV only.

A test is needed.

If(
IsEmpty(ListItem([Album],1,BWV)),
,
BWV ListItem([Album],1,BWV)
)

If list item[1] is empty, BWV is not in the album so do nothing, otherwise get the BWV.

 

As you might have guessed BWV (Bach-Werke-Verzeichnis) applies to the works of JS Bach only.
We can simply repeat the expression above for other composers

 

Beethoven: Piano Sonata No. 26 in E flat major ('Les Adieux') Op. 81a
Schumann: Waldszenen op. 82

If(
IsEmpty(ListItem([Album],1,op.)),
,
Op. ListItem([Album],1,op.)
)

This works for all works with op. in it, Op. doesn't work. Obvious the use of the delimiter is case sensitive. To avoid repeating everything for each variation is case, a conversion to lower case is needed.

If(
IsEmpty(ListItem(FixCase([Album],4),1,op.)),
,
Op. ListItem(FixCase([Album],4),1,op.)
)

FixCase converts to lower (4) and must be done two times.

 

Up to now, the opus numbers are at the end of the work.
What to do if this is not the case.

 

Brahms: Sonata for Violin & Piano no. 2 in A major Op. 100 (Thun)
Brahms: Intermezzo Op.117 – Lupu

 

The trick is to make a list of a list


If(
IsEmpty(ListItem(FixCase([Album],4),1,op.)),
,
Op. ListItem(ListItem(FixCase([Album],4),1,op.),0,-)
)

ListItem(FixCase([Album],4),1,op.)) gives us everything after op.
Wrap a second ListItem around using as a delimiter.
This gives us all characters up to the so this time we need the first ListItem.

 

To avoid repeating this for every possible delimiter, use the replace function.

 

If(
IsEmpty(ListItem(FixCase([Album],4),1,op.)),
,
Op. ListItem(ListItem(Replace(Replace(FixCase([Album],4),/(,;),-,;),1,op.),0)
)

Before building the second list, replace ( and – by ;
; is the default delimiter used in building lists.

 

I do have BWV, KV, D, WoO and Op.
For you barbarians out there Bach-Werke-Verzeichnis, Köchel-Verzeichnis, Deutsch, Werke ohne Opus Nummer and opus.
Simple combine them.

 

Schubert: Sonatina for violin & piano in A minor D. 385 (Op. posth. 137/2)

As we have both D. and Op. start with Schubert to extract the D.

 

If(IsEmpty(ListItem(FixCase([Album],4),1,d.)),
 If(IsEmpty(ListItem(FixCase([Album],4),1,bwv)),
  If(IsEmpty(ListItem(FixCase([Album],4),1,op.)),
   If(IsEmpty(ListItem(FixCase([Album],4),1,woo)),
    If(IsEmpty(ListItem(FixCase([Album],4),1,kv)),
     ,
     KV ListItem(FixCase([Album],4),1,kv)
     ),
     WoO ListItem(FixCase([Album],4),1,woo)
     ),
    Op. ListItem(ListItem(Replace(Replace(FixCase([Album],4),/(,;),-,;),1,op.),0)
    ),
  BWV ListItem(FixCase([Album],4),1,bwv)
  ),
D. ListItem(ListItem(Replace(Replace(FixCase([Album],4),/(,;),/,,;),1,d.),0)

)

 

 

All this code has been developed using an expression column.
As it is a calculated column, values will change as the album title changes.
Convenient as each time a composition is added, the opus is calculated.
However, once calculated and right, it might be convenient to store it in a custom tag to avoid messing it up when editing album titles.

 

How to get the values of an expression column into a normal tag?
In options > library you can define a custom tag
The library tool Move/Copy allows you to copy or move from one field to another but you can’t select an expression column

 

Tried the Excel style expression in the custom tag: =[My Expression]
Obvious My Expression is not recognized as a field.

Copy the entire expression and prefix it with =

Obvious the result is not as expected

Because of the endless nesting I use a multi-line layout.
Pasting this as an Excel style expression in the field only transfers the first line.

 

The trick is to get rid of the multi-line layout.
You can remove all CR by hand or

Change the field from User to Calculated and paste the formula

Close the expression editor, re-open and copy the formula.

When stored the expression is transformed to a single line.
Set the tag back to User
Paste this single line formula as an Excel style expression

Sigh....

 

Today you can use REGEX (Regular Expressions) like

Regex([Album], /#(Op\.|BWV) ?([^(]+)#/, -1)/
if(isequal([R1], op., 1), FixCase([R1],2),[R1]) [R2]

to do the job.

Little problem: what does this syntax means?