ssb22 / jianpu-ly

Jianpu in Lilypond
http://ssb22.user.srcf.net/mwrhome/jianpu-ly.html
Apache License 2.0
70 stars 18 forks source link

`process_input` output different lilypond sources when inputting same jianpu source mulitple times #35

Closed SilverRainZ closed 1 year ago

SilverRainZ commented 1 year ago

Hello, 好久不见,thank for you awesome script :D

I found my sphinx extension can only correctly generate the first score in my document, so the problem is found.

Step to reproduce:

from hashlib import sha256
import importlib  
jianpu = importlib.import_module("jianpu-ly")

jp = '1 2 3 4'
ly1 = jianpu.process_input(jp)
ly2 = jianpu.process_input(jp)

print(sha256(bytes(ly1, 'utf-8')).hexdigest())
print(sha256(bytes(ly2, 'utf-8')).hexdigest())

with open('./1.ly', 'w') as f:
    f.write(ly1)

with open('./2.ly', 'w') as f:
    f.write(ly2)

The checksum of ly1 and ly2 are different:

553796193b8a9aeb860f71b6474eae77c8005401bad91f36e560938636cf13da
56482a0f2fb963dc3e6d28f34970f4b4df60849146261bcbe615f814955edbf6

Diff 1.ly and 2.ly:

diff --git a/1.ly b/2.ly
index cc90b1a..e1326e2 100644
--- a/1.ly
+++ b/2.ly
@@ -36,7 +36,7 @@
     \override StaffSymbol.line-count = #0 %% tested in 2.15.40, 2.16.2, 2.18.0, 2.18.2, 2.20.0 and 2.22.2
     \override BarLine.bar-extent = #'(-2 . 2) %% LilyPond 2.18: please make barlines as high as the time signature even though we're on a RhythmicStaff (2.16 and 2.15 don't need this although its presence doesn't hurt; Issue 3685 seems to indicate they'll fix it post-2.18)
     }
-    { \new Voice="W" {
+    { \new Voice="Y" {

     \override Beam.transparent = ##f % (needed for LilyPond 2.18 or the above switch will also hide beams)
     \override Stem.direction = #DOWN
@@ -53,43 +53,7 @@

     \override Staff.TimeSignature.style = #'numbered
     \override Staff.Stem.transparent = ##t
-     #(define (note-one grob grob-origin context)
-  (if (and (eq? (ly:context-property context 'chordChanges) #t)
-      (or (grob::has-interface grob 'note-head-interface)
-        (grob::has-interface grob 'rest-interface)))
-    (begin
-      (ly:grob-set-property! grob 'stencil
-        (grob-interpret-markup grob
-          (make-lower-markup 0.5 (make-bold-markup "1")))))))
-  \applyOutput #'Voice #note-one c'4
-#(define (note-two grob grob-origin context)
-  (if (and (eq? (ly:context-property context 'chordChanges) #t)
-      (or (grob::has-interface grob 'note-head-interface)
-        (grob::has-interface grob 'rest-interface)))
-    (begin
-      (ly:grob-set-property! grob 'stencil
-        (grob-interpret-markup grob
-          (make-lower-markup 0.5 (make-bold-markup "2")))))))
-  \applyOutput #'Voice #note-two d'4
-#(define (note-three grob grob-origin context)
-  (if (and (eq? (ly:context-property context 'chordChanges) #t)
-      (or (grob::has-interface grob 'note-head-interface)
-        (grob::has-interface grob 'rest-interface)))
-    (begin
-      (ly:grob-set-property! grob 'stencil
-        (grob-interpret-markup grob
-          (make-lower-markup 0.5 (make-bold-markup "3")))))))
-  \applyOutput #'Voice #note-three e'4
-#(define (note-four grob grob-origin context)
-  (if (and (eq? (ly:context-property context 'chordChanges) #t)
-      (or (grob::has-interface grob 'note-head-interface)
-        (grob::has-interface grob 'rest-interface)))
-    (begin
-      (ly:grob-set-property! grob 'stencil
-        (grob-interpret-markup grob
-          (make-lower-markup 0.5 (make-bold-markup "4")))))))
-  \applyOutput #'Voice #note-four f'4
-\bar "|." } }
+       \applyOutput #'Voice #note-one c'4   \applyOutput #'Voice #note-two d'4   \applyOutput #'Voice #note-three e'4   \applyOutput #'Voice #note-four f'4 \bar "|." } }
 % === END JIANPU STAFF ===

 >>
@@ -99,7 +63,7 @@
 << 

 % === BEGIN MIDI STAFF ===
-    \new Staff { \new Voice="X" { c'4 d'4 e'4 f'4 } }
+    \new Staff { \new Voice="Z" { c'4 d'4 e'4 f'4 } }
 % === END MIDI STAFF ===

 >>
ssb22 commented 1 year ago

Ah, I didn't imagine process_input would be called more than once.

It uses global module state for things like "which jianpu note-heads have already been defined". So if you want to call it more than once, you'll have to reload the module:

ly1 = jianpu.process_input(jp)
importlib.reload(jianpu)
ly2 = jianpu.process_input(jp)

I should probably get it to check if you're calling it a second time and raise an error to tell you to do this....

SilverRainZ commented 1 year ago

I get it, I will reload the module after every process_input.

Thank you.