]> git.donarmstrong.com Git - lilypond.git/blobdiff - Documentation/contributor/programming-work.itexi
Fix typos in the English manual.
[lilypond.git] / Documentation / contributor / programming-work.itexi
index d6d54c7833ea3e19cdb1b09402d0f480c0e468fd..1a938cad0fe4438f86f62cb4debe559ec30b6f9a 100644 (file)
@@ -131,12 +131,12 @@ METAFONT tutorial page}.
 PostScript is used to generate graphical output.  A brief PostScript tutorial
 is @uref{http://local.wasp.uwa.edu.au/~pbourke/dataformats/postscript/,
 available online}.  The
-@uref{http://www.adobe.com/devnet/postscript/pdfs/PLRM.pdf, PostScript Lanugage
+@uref{http://www.adobe.com/devnet/postscript/pdfs/PLRM.pdf, PostScript Language
 Reference} is available online in PDF format.
 
 @subsection Python
 
-Python is used for XML2ly and is used for buillding the documentation and the
+Python is used for XML2ly and is used for building the documentation and the
 website.
 
 Python documentation is available at @uref{http://www.python.org/doc/,
@@ -200,7 +200,7 @@ describes a process for finding interesting code.
 @subsection Using the ROADMAP
 
 The file ROADMAP is located in the main directory of the lilypond source.
-ROADMAP lists all of the directories in the LilPond source tree, along
+ROADMAP lists all of the directories in the LilyPond source tree, along
 with a brief description of the kind of files found in each directory.
 This can be a very helpful tool for deciding which directories to search
 when looking for a function.
@@ -406,7 +406,7 @@ set number
 autocmd BufWritePre * :%s/\s\+$//e
 @end verbatim
 
-With this .vimrc, files can be reindented automatically by highlihting
+With this .vimrc, files can be reindented automatically by highlighting
 the lines to be indented in visual mode (use V to enter visual mode)
 and pressing =.
 
@@ -416,19 +416,28 @@ was suggested by Patrick McCarty.  It should be saved in
 
 @verbatim
 " Additional Guile-specific 'forms'
-syn keyword schemeSyntax define-public define* define-safe-public
+syn keyword schemeSyntax define-public define*-public
+syn keyword schemeSyntax define* lambda* let-keywords*
+syn keyword schemeSyntax defmacro defmacro* define-macro
+syn keyword schemeSyntax defmacro-public defmacro*-public
 syn keyword schemeSyntax use-modules define-module
-syn keyword schemeSyntax defmacro-public define-macro
-syn keyword schemeSyntax define-markup-command
-syn keyword schemeSyntax define-markup-list-command
-syn keyword schemeSyntax let-keywords* lambda* define*-public
-syn keyword schemeSyntax defmacro* defmacro*-public
+syn keyword schemeSyntax define-method define-class
+
+" Additional LilyPond-specific 'forms'
+syn keyword schemeSyntax define-markup-command define-markup-list-command
+syn keyword schemeSyntax define-safe-public define-music-function
+syn keyword schemeSyntax def-grace-function
 
 " All of the above should influence indenting too
-set lw+=define-public,define*,define-safe-public,use-modules,define-module
-set lw+=defmacro-public,define-macro
+set lw+=define-public,define*-public
+set lw+=define*,lambda*,let-keywords*
+set lw+=defmacro,defmacro*,define-macro
+set lw+=defmacro-public,defmacro*-public
+set lw+=use-modules,define-module
+set lw+=define-method,define-class
 set lw+=define-markup-command,define-markup-list-command
-set lw+=let-keywords*,lambda*,define*-public,defmacro*,defmacro*-public
+set lw+=define-safe-public,define-music-function
+set lw+=def-grace-function
 
 " These forms should not influence indenting
 set lw-=if
@@ -647,7 +656,7 @@ _f ("cannot find character number: %d", i)
 
 @item
 Think about translation issues. In a lot of cases, it is better to
-translate a whole message. The english grammar must not be imposed
+translate a whole message. The English grammar must not be imposed
 on the translator. So, instead of
 
 @example
@@ -690,7 +699,7 @@ _f ("Huh?  Not a Request: `%s'.  Ignoring.", request)
 
 @item
 Do not modularize too much; words frequently cannot be translated
-without context. It is probably safe to treat most occurences of
+without context. It is probably safe to treat most occurrences of
 words like stem, beam, crescendo as separately translatable words.
 
 @item
@@ -752,7 +761,7 @@ passed to the called functions.
 
 The GNU debugger, gdb, is the principal tool for debugging C++ code.
 
-@unnumberedsubsubsec Compiling LilyPond for use with gdb
+@subheading Compiling LilyPond for use with gdb
 
 In order to use gdb with LilyPond, it is necessary to compile
 LilyPond with debugging information.  This is accomplished by running
@@ -771,7 +780,7 @@ You should not do @var{make install} if you want to use a debugger
 with LilyPond.  The @var{make install} command will strip debugging
 information from the LilyPond binary.
 
-@unnumberedsubsubsec Typical gdb usage
+@subheading Typical gdb usage
 
 Once you have compiled the Lilypond image with the necessary
 debugging information it will have been written to a location in a
@@ -783,23 +792,24 @@ out/bin/lilypond
 
 This is important as you will need to let gdb know where to find the
 image containing the symbol tables.  You can invoke gdb from the
-command line using
+command line using the following:
 
 @example
 gdb out/bin/lilypond
 @end example
 @noindent
 This loads the LilyPond symbol tables into gdb.  Then, to run
-LilyPond on @code{test.ly} under the debugger, enter
+LilyPond on @code{test.ly} under the debugger, enter the following:
 
 @example
 run test.ly
 @end example
+
 @noindent
 at the gdb prompt.
 
 As an alternative to running gdb at the command line you may try
-a graphical interface to gdb such as ddd
+a graphical interface to gdb such as ddd:
 
 @example
 ddd out/bin/lilypond
@@ -808,7 +818,7 @@ ddd out/bin/lilypond
 You can also use sets of standard gdb commands stored in a .gdbinit
 file (see next section).
 
-@unnumberedsubsubsec Typical .gdbinit files
+@subheading Typical .gdbinit files
 
 The behavior of gdb can be readily customized through the use of a
 @var{.gdbinit} file.  A @var{.gdbinit} file is a file named
@@ -848,7 +858,7 @@ interpreter @code{top-repl}.  You can either investigate
 interactively using just Guile or you can use the debugging
 tools available within Guile.
 
-@unnumberedsubsubsec Using Guile interactively with LilyPond
+@subheading Using Guile interactively with LilyPond
 
 In order to experiment with Scheme programming in the LilyPond
 environment, it is necessary to have a Guile interpreter that
@@ -907,7 +917,7 @@ guile> (quit)
 
 The compilation of the .ly file will then continue.
 
-@unnumberedsubsubsec Using the Guile debugger
+@subheading Using the Guile debugger
 
 To set breakpoints and/or enable tracing in Scheme functions, put
 
@@ -921,7 +931,7 @@ up the environment for the debug command-line.  When your input file
 is processed, a guile prompt will be displayed.  You may now enter
 commands to set up breakpoints and enable tracing by the Guile debugger.
 
-@unnumberedsubsubsec Using breakpoints
+@subheading Using breakpoints
 
 At the guile prompt, you can set breakpoints with
 the @code{set-break!} procedure:
@@ -992,7 +1002,7 @@ print-book-with:
 (set-break! print-book-with)
 @end example
 
-@unnumberedsubsubsec Tracing procedure calls and evaluator steps
+@subheading Tracing procedure calls and evaluator steps
 
 Two forms of trace are available:
 
@@ -1045,7 +1055,7 @@ number of different platforms:
 
 In order for the Graphviz tool to work, config.make must be modified.
 It is probably a good idea to first save a copy of config.make under
-a different name.  Then, edit config.make by removing every occurence
+a different name.  Then, edit config.make by removing every occurrence
 of @code{-DNDEBUG}.
 
 @item Rebuilding LilyPond
@@ -1056,10 +1066,10 @@ The executable code of LilyPond must be rebuilt from scratch:
 make -C lily clean && make -C lily
 @end example
 
-@item Create a graphviz-compatible .ly file
+@item Create a graphviz-compatible @file{.ly} file
 
-In order to use the graphviz utility, the .ly file must include
-@file{ly/graphviz-init.ly}, and should then specify the
+In order to use the graphviz utility, the @file{.ly} file must include
+@file{ly/@/graphviz@/-init@/.ly}, and should then specify the
 grobs and symbols that should be tracked.  An example of this
 is found in @file{input/regression/graphviz.ly}.
 
@@ -1076,7 +1086,7 @@ lilypond graphviz.ly 2> graphviz.log
 
 The logfile has standard lilypond output, as well as the Graphviz
 output data.  Delete everything from the beginning of the file
-up to but not including the first occurence of @code{digraph}.
+up to but not including the first occurrence of @code{digraph}.
 
 @item Process the logfile with @code{dot}
 
@@ -1109,6 +1119,22 @@ ensure that the feature is properly integrated to maintain
 its long-term support.  This section describes the steps necessary
 for feature addition and modification.
 
+
+@menu
+* Write the code::
+* Write regression tests::
+* Write convert-ly rule::
+* Automatically update auxiliary information::
+* Manually update auxiliary information::
+* Edit changes.tely::
+* Verify successful build::
+* Verify regression tests::
+* Post patch for comments::
+* Push patch::
+* Closing the issues::
+@end menu
+
+@node Write the code
 @subsection Write the code
 
 You should probably create a new git branch for writing the code, as that
@@ -1118,6 +1144,8 @@ to work on small projects related to master.
 Please be sure to follow the rules for programming style discussed
 earlier in this chapter.
 
+
+@node Write regression tests
 @subsection Write regression tests
 
 In order to demonstrate that the code works properly, you will
@@ -1134,6 +1162,8 @@ multiple-issue regression test.
 Use existing regression tests as templates to demonstrate the type of
 header information that should be included in a regression test.
 
+
+@node Write convert-ly rule
 @subsection Write convert-ly rule
 
 If the modification changes the input syntax, a convert-ly rule
@@ -1147,7 +1177,9 @@ of the file.  In some cases, this will not be possible, so the
 rule will simply point out to the user that the feature needs
 manual correction.
 
-@subsection Automatically update documentation, snippets, and regtests
+
+@node Automatically update auxiliary information
+@subsection Automatically update auxiliary information
 
 convert-ly should be used to update the documentation, the snippets,
 and the regression tests.  This not only makes the necessary syntax
@@ -1178,7 +1210,9 @@ find input/regression/ -name '*.ly' | xargs convert-ly -e --from @qq{@var{X.Y.Z}
 
 @end example
 
-@subsection Manually update documentation, snippets, and regtests
+
+@node Manually update auxiliary information
+@subsection Manually update auxiliary information
 
 Where the convert-ly rule is not able to automatically update the inline
 lilypond code in the documentation (i.e. if a NOT_SMART rule is used), the
@@ -1191,7 +1225,7 @@ English version of the documentation.
 Where the convert-ly rule is not able to automatically update snippets
 in Documentation/snippets/, those snippets must be manually updated.
 Those snippets should be copied to Documentation/snippets/new.  The
-comments at the top of the snippet describing its automatice generation
+comments at the top of the snippet describing its automatic generation
 should be removed.  All translated texidoc strings should be removed.
 The comment @qq{% begin verbatim} should be removed.  The syntax of
 the snippet should then be manually edited.
@@ -1230,6 +1264,8 @@ write it from the regression tests.  The text that is added to
 or removed from the documentation should be changed only in
 the English version.
 
+
+@node Edit changes.tely
 @subsection Edit changes.tely
 
 An entry should be added to Documentation/changes.tely to describe
@@ -1243,6 +1279,8 @@ New entries in changes.tely go at the top of the file.
 The changes.tely entry should be written to show how the new change
 improves LilyPond, if possible.
 
+
+@node Verify successful build
 @subsection Verify successful build
 
 When the changes have been made, successful completion must be
@@ -1259,12 +1297,80 @@ considered to function successfully.
 Developers on Windows who are unable to build LilyPond should
 get help from a Linux or OSX developer to do the make tests.
 
-@subsection Verify regression test
+
+@node Verify regression tests
+@subsection Verify regression tests
 
 In order to avoid breaking LilyPond, it is important to verify that
-the regression tests all succeed.  This process is described in
-@ref{Regression tests}.
+the regression tests succeed, and that no unwanted changes are
+introduced into the output.  This process is described in
+@ref{Identifying code regressions}.
+
+@subheading Typical developer's edit/compile/test cycle
+
+TODO: is @code{[-j@var{X} CPU_COUNT=@var{X}]} useful for
+@code{test-baseline}, @code{check}, @code{clean},
+@code{test-redo}?  Neil Puttock says it is useful for
+everything but @code{clean}, which is disk-limited.
+Need to check formally.
+
+@itemize
+@item
+Initial test:
+
+@example
+make [-j@var{X}]
+make test-baseline
+make [-j@var{X} CPU_COUNT=@var{X}] check
+@end example
+
+@item
+Edit/compile/test cycle:
+
+@example
+@emph{## edit source files, then...}
+
+make clean                    @emph{## only if needed (see below)}
+make [-j@var{X}]                    @emph{## only if needed (see below)}
+make test-redo                @emph{## redo files differing from baseline}
+make [-j@var{X} CPU_COUNT=@var{X}] check  @emph{## CPU_COUNT here?}
+@end example
+
+@item
+Reset:
+
+@example
+make test-clean
+@end example
+@end itemize
+
+If you modify any source files that have to be compiled (such as
+@file{.cc} or @file{.hh} files in @file{flower/} or @file{lily/}),
+then you must run @command{make} before @command{make test-redo},
+so @command{make} can compile the modified files and relink all
+the object files.  If you only modify files which are interpreted,
+like those in the @file{scm/} and @file{ly/} directories, then
+@command{make} is not needed before @command{make test-redo}.
+
+TODO:  Fix the following paragraph.  You can do @command{rm mf/out/*}
+instead of make clean, and you can probably do
+@command{make -C  mf/ clean} as well, but I haven't checked it -- cds
+
+Also, if you modify any font definitions in the @file{mf/}
+directory then you must run @command{make clean} and
+@command{make} before running @command{make test-redo}.  This will
+recompile everything, whether modified or not, and takes a lot
+longer.
 
+Running @command{make@tie{}check} will leave an HTML page
+@file{out/@/test@/-results/@/index@/.html}.  This page shows all the
+important differences that your change introduced, whether in the
+layout, MIDI, performance or error reporting.
+
+
+
+
+@node Post patch for comments
 @subsection Post patch for comments
 
 For any change other than a minor change, a patch set should be
@@ -1327,6 +1433,22 @@ As revisions are made in response to comments, successive patch sets
 for the same issue can be uploaded by reissuing the git-cl command
 with the modified branch checked out.
 
+Sometimes in response to comments on revisions, the best way to
+work may require creation of a new branch in git.  In order to
+associate the new branch with an existing Rietveld issue,
+the following command can be used:
+
+@example
+git cl issue issue-number
+@end example
+
+@noindent
+where @code{issue-number} is the number of the existing Rietveld
+issue.
+
+
+
+@node Push patch
 @subsection Push patch
 
 Once all the comments have been addressed, the patch can be pushed.
@@ -1334,6 +1456,8 @@ Once all the comments have been addressed, the patch can be pushed.
 If the author has push privileges, the author will push the patch.
 Otherwise, a developer with push privileges will push the patch.
 
+
+@node Closing the issues
 @subsection Closing the issues
 
 Once the patch has been pushed, all the relevant issues should be
@@ -1351,6 +1475,7 @@ the author does not have privileges to change the status, an email
 should be sent to bug-lilypond requesting the BugMeister to change
 the status.
 
+
 @node Iterator tutorial
 @section Iterator tutorial
 
@@ -1360,6 +1485,7 @@ Iterators are routines written in C++ that process music expressions
 and sent the music events to the appropriate engravers and/or
 performers.
 
+
 @node Engraver tutorial
 @section Engraver tutorial
 
@@ -1374,6 +1500,17 @@ the engraver in time-step order during the iteration phase.  Grobs are
 made available to the engraver when they are created by other engravers
 during the iteration phase.
 
+
+@menu
+* Useful methods for information processing::
+* Translation process::
+* Preventing garbage collection for SCM member variables::
+* Listening to music events::
+* Acknowledging grobs::
+* Engraver declaration/documentation::
+@end menu
+
+@node Useful methods for information processing
 @subsection Useful methods for information processing
 
 An engraver inherits the following public methods from the Translator
@@ -1397,6 +1534,8 @@ of context properties before translation starts, whereas
 translation: for example, an unterminated spanner might be completed
 automatically or reported with a warning message.
 
+
+@node Translation process
 @subsection Translation process
 
 At each timestep in the music, translation proceeds by calling the
@@ -1417,6 +1556,8 @@ within engravers.
 information has been processed prior to beginning the translation for
 the next timestep.
 
+
+@node Preventing garbage collection for SCM member variables
 @subsection Preventing garbage collection for SCM member variables
 
 In certain cases, an engraver might need to ensure private Scheme
@@ -1433,6 +1574,7 @@ Engraver_name::derived_mark ()
 @end example
 
 
+@node Listening to music events
 @subsection Listening to music events
 
 External interfaces to the engraver are implemented by protected
@@ -1459,6 +1601,8 @@ Engraver_name::listen_event_name (Stream event *event)
 @}
 @end example
 
+
+@node Acknowledging grobs
 @subsection Acknowledging grobs
 
 Some engravers also need information from grobs as they are created
@@ -1494,6 +1638,8 @@ Engraver_name::acknowledge_interface_name (Grob_info info)
 @}
 @end example
 
+
+@node Engraver declaration/documentation
 @subsection Engraver declaration/documentation
 
 An engraver must have a public macro
@@ -1525,6 +1671,14 @@ is the name of the interface that will be acknowledged,
 and @code{Engraver_writes} is the set of properties written by
 the engraver.
 
+The @code{ADD_ACKNOWLEDGER} and @code{ADD_TRANSLATOR} macros use a
+non-standard indentation system.  Each interface, grob, read property,
+and write property is on its own line, and the closing parenthesis
+and semicolon for the macro all occupy a separate line beneath the final
+interface or write property.  See existing engraver files for more
+information.
+
+
 @node Callback tutorial
 @section Callback tutorial
 
@@ -1574,6 +1728,14 @@ This is a place to dump information that may be of use to developers
 but doesn't yet have a proper home.  Ideally, the length of this section
 would become zero as items are moved to other homes.
 
+
+@menu
+* Spacing algorithms::
+* Info from Han-Wen email::
+* Music functions and GUILE debugging::
+@end menu
+
+@node Spacing algorithms
 @subsection Spacing algorithms
 
 Here is information from an email exchange about spacing algorithms.
@@ -1599,7 +1761,9 @@ We create lots of extra grobs (eg. a BarNumber at every bar line) but
 most of them are not drawn. See the break-visibility property in
 item-interface.
 
-@subsection Info from Han-Wen Email
+
+@node Info from Han-Wen email
+@subsection Info from Han-Wen email
 
 In 2004, Douglas Linhardt decided to try starting a document that would
 explain LilyPond architecture and design principles.  The material below
@@ -1608,29 +1772,29 @@ is extracted from that email, which can be found at
 The headings reflect questions from Doug or comments from Han-Wen;
 the body text are Han-Wen's answers.
 
-@unnumberedsubsubsec Figuring out how things work.
+@subheading Figuring out how things work.
 
 I must admit that when I want to know how a program works, I use grep
 and emacs and dive into the source code. The comments and the code
 itself are usually more revealing than technical documents.
 
-@unnumberedsubsubsec What's a grob, and how is one used?
+@subheading What's a grob, and how is one used?
 
 Graphical object - they are created from within engravers, either as
 Spanners (derived class) -slurs, beams- or Items (also a derived
 class) -notes, clefs, etc.
 
 There are two other derived classes System (derived from Spanner,
-contaning a "line of music") and Paper_column (derived from Item, it
+containing a "line of music") and Paper_column (derived from Item, it
 contains all items that happen at the same moment). They are separate
 classes because they play a special role in the linebreaking process.
 
-@unnumberedsubsubsec What's a smob, and how is one used?
+@subheading What's a smob, and how is one used?
 
 A C(++) object that is encapsulated so it can be used as a Scheme
 object.  See GUILE info, "19.3 Defining New Types (Smobs)"
 
-@unnumberedsubsubsec When is each C++ class constructed and used
+@@subheading When is each C++ class constructed and used
 
 @itemize
 
@@ -1676,7 +1840,7 @@ BTW, the entry point for interpreting is ly:run-translator
 
 @end itemize
 
-@unnumberedsubsubsec Can you get to Context properties from a Music object?
+@subheading Can you get to Context properties from a Music object?
 
 You can create music object with a Scheme function that reads context
 properties (the \applycontext syntax). However, that function is
@@ -1684,34 +1848,34 @@ executed during Interpreting, so you can not really get Context
 properties from Music objects, since music objects are not directly
 connected to Contexts. That connection is made by the  Music_iterators
 
-@unnumberedsubsubsec Can you get to Music properties from a Context object?
+@subheading Can you get to Music properties from a Context object?
 
 Yes, if you are given the music object within a Context
 object. Normally, the music objects enter Contexts in synchronized
 fashion, and the synchronization is done by Music_iterators.
 
-@unnumberedsubsubsec What is the relationship between C++ classes and Scheme objects?
+@subheading What is the relationship between C++ classes and Scheme objects?
 
 Smobs are C++ objects in Scheme. Scheme objects (lists, functions) are
 manipulated from C++ as well using the GUILE C function interface
 (prefix: scm_)
 
-@unnumberedsubsubsec How do Scheme procedures get called from C++ functions?
+@subheading How do Scheme procedures get called from C++ functions?
 
 scm_call_*, where * is an integer from 0 to 4.
 Also scm_c_eval_string (), scm_eval ()
 
-@unnumberedsubsubsec How do C++ functions get called from Scheme procedures?
+@subheading How do C++ functions get called from Scheme procedures?
 
 Export a C++ function to Scheme with LY_DEFINE.
 
-@unnumberedsubsubsec What is the flow of control in the program?
+@subheading What is the flow of control in the program?
 
 Good question.  Things used to be clear-cut, but we have Scheme
 and SMOBs now, which means that interactions do not follow a very
 rigid format anymore. See below for an overview, though.
 
-@unnumberedsubsubsec Does the parser make Scheme procedure calls or C++ function calls?
+@subheading Does the parser make Scheme procedure calls or C++ function calls?
 
 Both. And the Scheme calls can call C++ and vice versa. It's nested,
 with the SCM datatype as lubrication between the interactions
@@ -1719,7 +1883,7 @@ with the SCM datatype as lubrication between the interactions
 (I think the word "lubrication" describes the process better than the
 traditional word "glue")
 
-@unnumberedsubsubsec How do the front-end and back-end get started?
+@subheading How do the front-end and back-end get started?
 
 Front-end: a file is parsed, the rest follows from that. Specifically,
 
@@ -1765,26 +1929,26 @@ page-breaking, so now the backend also involves Paper_book,
 Paper_lines and other things. This area is still heavily in flux, and
 perhaps not something you should want to look at.
 
-@unnumberedsubsubsec How do the front-end and back-end communicate?
+@subheading How do the front-end and back-end communicate?
 
 There is no communication from backend to front-end. From front-end to
 backend is simply the program flow: music + definitions gives
 contexts, contexts yield output, after processing, output is written
 to disk.
 
-@unnumberedsubsubsec Where is the functionality associated with KEYWORDs?
+@subheading Where is the functionality associated with KEYWORDs?
 
 See my-lily-lexer.cc (keywords, there aren't that many) and ly/*.ly
 (most of the other backslashed \words are identifiers)
 
-@unnumberedsubsubsec What Contexts/Properties/Music/etc. are available when they are processed?
+@subheading What Contexts/Properties/Music/etc. are available when they are processed?
 
 What do you mean exactly with this question?
 
 See ly/engraver-init.ly for contexts, see scm/define-*.scm for other
 objects.
 
-@unnumberedsubsubsec How do you decide if something is a Music, Context, or Grob property?
+@subheading How do you decide if something is a Music, Context, or Grob property?
 Why is part-combine-status a Music property when it seems (IMO)
 to be related to the Staff context?
 
@@ -1801,9 +1965,11 @@ part-combine-status is part of such a synthetic event, used by
 Part_combine_iterator to communicate with Part_combine_engraver.
 
 
-@unnumberedsubsubsec I'm adding a property to affect how \autochange works.  It seems to
+@subheading Deciding between context and music properties
+
+I'm adding a property to affect how \autochange works.  It seems to
 me that it should be a context property, but the Scheme autochange
-procecure has a Music argument.  Does this mean I should use
+procedure has a Music argument.  Does this mean I should use
 a Music property?
 
 \autochange is one of these extra strange beasts: it requires
@@ -1826,10 +1992,75 @@ argument,
 where around-central-C is some function that is called from
 make-autochange-music.
 
-@unnumberedsubsubsec I get lost figuring out what environment the code I'm looking at is in when it executes.
-I found both the C++ and Scheme autochange code.  Then I was
-trying to figure out where the code got called from.  I finally figured out that
-the Scheme procedure was called before the C++ iterator code, but it took me a
+@subheading More on context and music properties
+
+From Neil Puttock, in response to a question about transposition:
+
+Context properties (using \set & \unset) are tied to engravers: they
+provide information relevant to the generation of graphical objects.
+
+Since transposition occurs at the music interpretation stage, it has
+no direct connection with engravers: the pitch of a note is fixed
+before a notehead is created.  Consider the following minimal snippet:
+
+@example
+@{ c' @}
+@end example
+
+This generates (simplified) a NoteEvent, with its pitch and duration
+as event properties,
+
+@example
+(make-music
+  'NoteEvent
+  'duration
+  (ly:make-duration 2 0 1 1)
+  'pitch
+  (ly:make-pitch 0 0 0)
+@end example
+
+which the Note_heads_engraver hears.  It passes this information on to
+the NoteHead grob it creates from the event, so the head's correct
+position and duration-log can be determined once it's ready for
+printing.
+
+If we transpose the snippet,
+
+@example
+\transpose c d @{ c' @}
+@end example
+
+the pitch is changed before it reaches the engraver (in fact, it
+happens just after the parsing stage with the creation of a
+TransposedMusic music object):
+
+@example
+(make-music
+ 'NoteEvent
+ 'duration
+ (ly:make-duration 2 0 1 1)
+ 'pitch
+ (ly:make-pitch 0 1 0)
+@end example
+
+You can see an example of a music property relevant to transposition:
+untransposable.
+
+@example
+\transpose c d @{ c'2 \withMusicProperty #'untransposable ##t c' @}
+@end example
+
+-> the second c' remains untransposed.
+
+Take a look at lily/music.cc to see where the transposition takes place.
+
+
+@subheading How do I tell about the execution environment?
+
+I get lost figuring out what environment the code I'm looking at is in when it
+executes.  I found both the C++ and Scheme autochange code.  Then I was trying
+to figure out where the code got called from.  I finally figured out that the
+Scheme procedure was called before the C++ iterator code, but it took me a
 while to figure that out, and I still didn't know who did the calling in the
 first place.  I only know a little bit about Flex and Bison, so reading those
 files helped only a little bit.
@@ -1844,6 +2075,7 @@ p ly_display_scm(obj)
 
 this will display OBJ through GUILE.
 
+@node Music functions and GUILE debugging
 @subsection Music functions and GUILE debugging
 
 Ian Hulin was trying to do some debugging in music functions, and
@@ -1882,7 +2114,7 @@ finds out about the breakpoint.
 
 Han-Wen answered as follows:
 
-You can see the defintion by doing
+You can see the definition by doing
 
 @example
 #(display conditionalMark)