Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Documentation rebuild #2837

Draft
wants to merge 12 commits into
base: dev
Choose a base branch
from

Conversation

ethancrawford
Copy link
Collaborator

@ethancrawford ethancrawford commented Sep 9, 2021

Purpose of this PR

To generate discussion about the best way forward for rebuilding the documentation system. Since some parallel work was also carried out by SunderB, there will need to be some compromises somewhere about which parts of either implementation to carry forward.

There are currently several issues with the existing documentation in the help panel:

  • The tutorial was the only help documentation that was translatable.
  • While the tutorial is available both in-app and on the Sonic Pi website, it is currently a very manual process to synchronise the tutorial between the two locations. This seems more labour-intensive than necessary, and prone to mistakes.

The work in this PR was originally started to address these issues: namely,

  • To allow all documentation in the help panel to be translatable.
  • To provide a single, portable data source containing the metadata that makes up the documentation, that is able to be synchronised between multiple host apps/websites/etc. (Potentially with a degree of automation. This would minimise the need for recurring manual labour to do so, and minimise the possibility of mistakes).

Implementation choices in this PR

Translation of the documentation

The proposed approach to making all of the documentation translatable is to stick with the existing translation framework, gettext. We would extract the text of the documentation metadata from the Ruby source code into a .pot file using Ruby's gettext gem.
(Since gettext will only work with string literals, it is necessary to first 'eval' the documentation metadata so that variable contents are output as raw strings. Once this is done, we can then extract the string literals into the .pot file).

This approach was deemed suitable since gettext is one of the most widely supported translation systems, and doing the translation from Ruby source code appeared reasonable since the prospect of later re-implementing the Sonic Pi DSL in a different language such as Elixir would most likely necessitate rewriting the documentation metadata from scratch anyway, so there would be more work down the line regardless of whether the metadata was extracted for translation from Ruby in the mean-time, or placed in some intermediate format first.

Portable documentation metadata

The proposed approach to making the documentation metadata portable/sharable between multiple 'host projects' is to extract the metadata into TOML files.
The reason for this particular data format is that it is already used in the Sonic Pi project for things such as configuration, and there is interest in using it further in future, such as for storage of custom synth metadata. Standardising on a single portable data format where possible seemed reasonable. TOML also appears to be fairly well supported in many programming languages.
Other data formats such as JSON and XML were considered, but TOML was ultimately chosen for the reason that it was already in use, and this would minimise the number of new technologies introduced into the project.

Parsing of documentation metadata from Sonic Pi DSL source code, HTML generation

The current approach of parsing metadata and generating html as interpolated strings directly from Ruby scripts mixes presentation code (html output) directly with server or app code. This is not very maintainable.

It is proposed to instead have dedicated templates that format and display the documentation metadata, separate from any Sonic Pi server code or build script.
The approach chosen in this PR was to use ERB to generate templates for the portable TOML files, instead of templates for HTML directly, to enable the portability of the documentation metadata as mentioned further above. Other templating engines were considered, such as Tilt and Slim, but ERB was chosen since it is already part of the Ruby standard library, and provides all of the functions we need. If the Ruby server code is later replaced with another language such as Elixir or Rust, there will be an equivalent library that allows code to be embedded into a text file in the same way, so the concept of using templates to produce intermediate files for the documentation is still suitable.

Storage, loading and displaying of documentation in the GUI

The documentation is currently partially embedded into the Qt GUI, so that it requires compiling the app to update it.
It is proposed to instead load the documentation into Sonic Pi via a web view/web browser embedded in the GUI, which avoids this problem.
Embedding a Qt web view into the GUI is straight forward, so the question then becomes how to create and package the HTML pages that are displayed through it.

Conversion of portable intermediate metadata files into HTML for the Sonic Pi GUI

The proposed approach was to use Elixir's Phoenix web framework to create a dynamic website, that kept the documentation metadata to be displayed in memory, rather than storing it in a database. A database was not as necessary in this case because there was not a large amount of information to store, and it was also mostly static data.
Phoenix was considered suitable for several reasons:

  • There is a desire to move away from Ruby for much of the internal code of Sonic Pi, so Ruby web frameworks such as Ruby on Rails, or static site generators such as Jekyll, Nanoc, Slate, etc were deemed less useful if the base language was intended to be changed in the not too distant future.
  • Erlang and Elixir are seen as desirable languages to move towards, which Phoenix is based on.
  • There was interest from Sam in using Elixir's/Phoenix's live views for other parts of the Sonic Pi GUI. This was seen as perhaps the strongest point in favour of using Phoenix. It made sense to use the same framework and libraries/functions for the documentation. Live views would be useful for swapping sections of documentation in and out when users navigate through it.
  • A dynamic web app would make certain features easier. This could include things such as:
    • Updating the documentation on the fly (for example, inserting new content if a custom synth is loaded into Sonic Pi at run-time).
    • Having access to Elixir/Erlang code at run-time, to provide advanced features. (Such a sending Sonic Pi scripts to the server to be run, straight from interaction with a html element, in the same way that the Samples page allows you to preview sample sounds).

Using a custom-built set of scripts to template and serve the HTML pages without the use of an existing web framework is possible, but would require a fair amount of work to plumb in enough features to become suitably flexible and useful. (Also, other things like live views and live components are quite specialised and would be difficult to replicate).

Below are a few diagrams giving a rough overview of the components and processes that the proposed documentation rebuild uses.

I am interested in hearing about anyone's opinions, particularly @SunderB and @samaaron, regarding my proposed approaches and reasoning, and am happy to elaborate or answer any further questions.

The work done here is also just a proof of concept, with only the bare minimum of functionality to demonstrate the various technologies involved. (For example, starting the web server up was not yet integrated into the Sonic Pi boot process, and neither is the new documentation website yet integrated into the Sonic Pi GUI). I'm aware that various parts will potentially need to be adjusted/tidied up/completed properly depending on the outcome of any discussion about their suitability.

How to run a copy of this code demonstrating the proposed documentation rebuild

  • Make sure the basic prerequisites of a recent-ish version of Node.js, preferably v14+, (only required for development) and Elixir ~> 1.7 are installed on your device
  • Check out the documentation_rebuild branch of ethancrawford/sonic-pi
  • build the app as normal according to the official build instructions
  • cd etc/docs
  • mix phx.server
  • visit localhost:4000 in a browser to see a basic documentation website.

Rough diagrams outlining the components and processes in the proposed documentation rebuild

Translation and conversion of Sonic Pi DSL metadata into a portable format

DSL translation

Basic overview of integrating a Phoenix web app and loading and displaying the documentation pages

Phoenix

@SunderB
Copy link
Contributor

SunderB commented Sep 9, 2021

Hey @ethancrawford,

Thank you for the great explanation and diagrams!
I'm just trying this out and when I try running mix phx.server I get this error at the end:

== Compilation error in file lib/docs_web/live/page_live/page_live.ex ==
** (CompileError) lib/docs_web/live/page_live/page_live.ex:3: cannot define module DocsWeb.PageLive because it is currently being defined in lib/docs_web/live/page_live.ex:1
    (elixir 1.12.2) lib/kernel/parallel_compiler.ex:319: anonymous fn/4 in Kernel.ParallelCompiler.spawn_workers/7

@ethancrawford
Copy link
Collaborator Author

Weird. I'll have to investigate that asap. I'll update in the next few hours...

@ethancrawford
Copy link
Collaborator Author

Ah. Probably a side effect of moving a bunch of those files into a sub-directory. Will fix it soon.

@ethancrawford
Copy link
Collaborator Author

@SunderB - out of curiosity, does mix compile --force then allow the server to start up successfully?

@SunderB
Copy link
Contributor

SunderB commented Sep 9, 2021

mix compile --force gives the same error

@SunderB
Copy link
Contributor

SunderB commented Sep 9, 2021

Oh wait, it seems there were some left over untracked files in the wrong folder. (I first tried to rebase it on dev branch, but realised that had been done already) After stashing those, it works!

@ethancrawford
Copy link
Collaborator Author

I don't expect so, but how about mix clean ? 🤞

@ethancrawford
Copy link
Collaborator Author

ethancrawford commented Sep 9, 2021

I'm wondering where those files came from, since lib/docs_web/live/page_live.ex shouldn't exist any more... (Ah, I see your updated comment). Phew!

@SunderB
Copy link
Contributor

SunderB commented Sep 9, 2021

The website works, but there seems to be no css. (I think the css file was cleared in the git stash) I'll try resetting the repo to your branch again.
Screenshot_20210909_131757

@SunderB
Copy link
Contributor

SunderB commented Sep 9, 2021

Still no apparent CSS apart from a top loading bar, is that expected?

Update: it seems like I'm missing Bootstrap

[info] GET /
[debug] Processing with Phoenix.LiveView.Plug.index/2
  Parameters: %{}                                                                                                                                                                            
  Pipelines: [:browser]                                                                                                                                                                      
[info] GET /js/bootstrap.bundle.min.js
[info] GET /css/bootstrap.min.css
[info] Sent 200 in 60ms
[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /css/bootstrap.min.css (DocsWeb.Router)
    (docs 0.1.0) lib/phoenix/router.ex:402: DocsWeb.Router.call/2                                                                                                                            
    (docs 0.1.0) lib/docs_web/endpoint.ex:1: DocsWeb.Endpoint.plug_builder_call/2                                                                                                            
    (docs 0.1.0) lib/plug/debugger.ex:132: DocsWeb.Endpoint."call (overridable 3)"/2                                                                                                         
    (docs 0.1.0) lib/docs_web/endpoint.ex:1: DocsWeb.Endpoint.call/2                                                                                                                         
    (phoenix 1.5.12) lib/phoenix/endpoint/cowboy2_handler.ex:65: Phoenix.Endpoint.Cowboy2Handler.init/4                                                                                      
    (cowboy 2.9.0) /mnt/Storage-Disk/Sunder/Documents/Coding/Sonic-Pi/ethancrawford_sonic-pi/etc/docs/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2                       
    (cowboy 2.9.0) /mnt/Storage-Disk/Sunder/Documents/Coding/Sonic-Pi/ethancrawford_sonic-pi/etc/docs/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3                    
    (cowboy 2.9.0) /mnt/Storage-Disk/Sunder/Documents/Coding/Sonic-Pi/ethancrawford_sonic-pi/etc/docs/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3            
    (stdlib 3.15.2) proc_lib.erl:226: :proc_lib.init_p_do_apply/3                                                                                                                            

[debug] ** (Phoenix.Router.NoRouteError) no route found for GET /js/bootstrap.bundle.min.js (DocsWeb.Router)                                                                                 
    (docs 0.1.0) lib/phoenix/router.ex:402: DocsWeb.Router.call/2                                                                                                                            
    (docs 0.1.0) lib/docs_web/endpoint.ex:1: DocsWeb.Endpoint.plug_builder_call/2                                                                                                            
    (docs 0.1.0) lib/plug/debugger.ex:132: DocsWeb.Endpoint."call (overridable 3)"/2                                                                                                         
    (docs 0.1.0) lib/docs_web/endpoint.ex:1: DocsWeb.Endpoint.call/2                                                                                                                         
    (phoenix 1.5.12) lib/phoenix/endpoint/cowboy2_handler.ex:65: Phoenix.Endpoint.Cowboy2Handler.init/4                                                                                      
    (cowboy 2.9.0) /mnt/Storage-Disk/Sunder/Documents/Coding/Sonic-Pi/ethancrawford_sonic-pi/etc/docs/deps/cowboy/src/cowboy_handler.erl:37: :cowboy_handler.execute/2                       
    (cowboy 2.9.0) /mnt/Storage-Disk/Sunder/Documents/Coding/Sonic-Pi/ethancrawford_sonic-pi/etc/docs/deps/cowboy/src/cowboy_stream_h.erl:306: :cowboy_stream_h.execute/3                    
    (cowboy 2.9.0) /mnt/Storage-Disk/Sunder/Documents/Coding/Sonic-Pi/ethancrawford_sonic-pi/etc/docs/deps/cowboy/src/cowboy_stream_h.erl:295: :cowboy_stream_h.request_process/3            
    (stdlib 3.15.2) proc_lib.erl:226: :proc_lib.init_p_do_apply/3   

@ethancrawford
Copy link
Collaborator Author

hmm, no. I'll see if I can reproduce it maybe

@SunderB
Copy link
Contributor

SunderB commented Sep 9, 2021

I downloaded Bootstrap 5.1.1 and placed the files in etc/docs/assets/static/(css/js), and it's working :)
Screenshot_20210909_135026

@ethancrawford
Copy link
Collaborator Author

Ok 👍

@ethancrawford
Copy link
Collaborator Author

Ah. It looks like the static folder is in the .gitignore 😂 😛

@ethancrawford
Copy link
Collaborator Author

I've switched to using bootstrap from npm, so that it's easier to include it in the webpacker pipeline. The styling would likely be completely changed at some point if this was ever going to be used anyway.

@SunderB
Copy link
Contributor

SunderB commented Sep 9, 2021

I'm just messing around with the phoenix HTML templates. Is there any way to set an attribute of an html element with a variables? (e.g. for links/anchors)

@SunderB
Copy link
Contributor

SunderB commented Sep 9, 2021

My thoughts so far:

General

  • I like the idea of the templates for synths, fx, lang pages, although it looks like the comments are copied over to the generated toml files. Is there a specific reason for that?
  • Also, apart from it already being used for audio preferences, are there other reasons for choosing TOML over JSON?

Website

  • I like the live reloading feature!
  • I really like the idea of using Phoenix templates in the HTML website generation - much better than shoving it in ruby strings!
  • The current website doesn't seem to have different links for individual doc pages. Is there a way to achieve that? (e.g. if someone wanted to bookmark a certain page)
  • Website styling - in regards to that, in trying to figure out the best way to create a doc website, I made a jekyll generated proof-of-concept sonic-pi docs website: https://sunderb.me/sonic-pi-docs-test.
    The style is based off of the GUI themes and online tutorial CSS, and I tried to make the sidebar resemble the GUI help interface.
    If we were to go ahead with using Phoenix to generate a website, then maybe some of the test website could be used?
  • Some of the docs are still in markdown, an haven't been converted to HTML. Is there a way we can get Phoenix to do this for us, or should it be done in ruby?
  • Will the tutorial be included? If so, will we continue using ruby to convert it to HTML?
  • Could the website be built to host statically using Phoenix?

Qt Docs

  • How would the html pages for the Qt GUI be created? Would we get Phoenix to generate them (without the navbar of course), or use ruby?
  • Would the files be hard-coded at compile time, or be indexed from a folder at runtime?
  • If compiled, then we may encounter issues with large .qrc and/or header files. In my implementation, I had to enable /bigobj compiler option on Windows for the CI to build properly, or have a seperate .cpp file handle the docs

@SunderB
Copy link
Contributor

SunderB commented Sep 9, 2021

Update:
I've been working on the website, and managed to fill out the synth/fx html pages, add some styling, and implement individual urls for each page:
Screenshot_20210910_004505

@ethancrawford
Copy link
Collaborator Author

ethancrawford commented Sep 10, 2021

Is there any way to set an attribute of an html element with a variables? (e.g. for links/anchors)

Yes, you can interpolate Elixir into the html attributes with { ... }. I do it to set the class of the nav elements:

 class={["disabled", is_active(@active_tab, :tutorial)]}

(This is a feature of the latest version of embedded elixir, HEex - or 'Html aware Embedded Elixir).

Replies to your next comments:

General

it looks like the comments are copied over to the generated toml files. Is there a specific reason for that?

Yes. My thinking was that if the docs metadata were to be copied into a new project such as an alternative GUI, or a plugin for a different text editor, then there would need to be some way to parse the metadata and create HTML in this external project, for it to be usable there. My thinking was that there would need to be some kind of indication in the metadata files about what each piece of data represented and/or how it was intended to be presented in the HTML. (Without this, it would be up to the contributor to attempt to compare the metadata with what they see in the Sonic Pi app itself to understand what it was and where it fit in in the UI).

Maybe I am overthinking it, but those were my thoughts about that 🙂

Also, apart from it already being used for audio preferences, are there other reasons for choosing TOML over JSON?

Not especially, but I know that Sam is keen to minimise the number of new technologies introduced into the project where possible.

Website

If we were to go ahead with using Phoenix to generate a website, then maybe some of the test website could be used?

The test website looks good - Sounds fine to me 🙂

Some of the docs are still in markdown, an haven't been converted to HTML. Is there a way we can get Phoenix to do this for us, or should it be done in ruby?

Will the tutorial be included? If so, will we continue using ruby to convert it to HTML?

I hadn't decided what to do about the markdown docs yet. My preference is of course to have all of the docs in the same format, so that we don't have to have separate functions to handle parsing different formats. In theory I'd go with a once off manual effort to convert the markdown to TOML, (assuming we use that for the intermediate format - or script this conversion depending on how time consuming it is) and then make phoenix live view/live component templates for the tutorial & examples just like I have done for the others. Ie, yes - the tutorial would be included - it's just another part of the docs, and my instinct would be to replace the current tutorial HTML conversion process by including the tutorial in the same process I've used for the other docs sections here.

Could the website be built to host statically using Phoenix?

Although Phoenix is not built for this by default, there are ways people have adapted Phoenix to act as a static site generator - here's a few examples:

Qt Docs

Maybe I'm misunderstanding your questions for this heading, but if you mean how is the documentation integrated into the GUI, I mention all that above in my introductory notes on the PR. Instead of embedding things like the contents list and links to the HTML files into the C++ code, we replace all that by making the documentation widget a Qt web view - meaning that we can render the docs website directly within the webview, navigation bar and all. The Qt app does not need to know anything about the docs website other than the URL to load into the web view.

@ethancrawford
Copy link
Collaborator Author

(Also, love what you've added to my experiment so far! - I was just under the impression that any work on our ideas was waiting until we decided how to move forward with either of them! 🤷‍♂️ 🙂 )

@SunderB
Copy link
Contributor

SunderB commented Sep 14, 2021

I made a table to help start comparing different aspects of the implementations. Tell me if anything needs adding :)

Step PR #2797 PR #2837
Method of extraction JSON objects manually created in Ruby code TOML ERB templates filled in using Ruby
Format of extracted reference info
  • JSON

  • one file per section per language - fewer but larger files

  • no comments

  • TOML - already used for audio settings

  • one file per item/page per language(?) - lots of smaller files

  • translatable(?) comments

  • Specifying translatable strings Specified in i18n-tool.rb, hardcoded Specified using _tr function in the TOML templates, includes labels/titles and constraints
    Generating Qt Docs
  • Basic HTML made using Ruby script

  • Copied to Qt help folder

  • Linked to sonic-pi executable using .qrc and header files - high memory usage at build time!

  • Docs widget split into seperate class (to modularise the code and reduce object sizes)

  • Use a Qt WebView to load the locally hosted Phoenix site - requires another running process to host it

  • Live reload when docs are updated/changed - could be used for adding docs about external synths

  • Should be easy to change languages dynamically or allow the user to read the docs in a different language to the UI language

  • Generating/hosting website pages
  • Basic HTML made using Ruby script

  • site made using Jekyll (Ruby based)

  • generates static website, could be viewed without serving

  • HTML generated and site made using Phoenix (Elixir based)

  • live server, by default requires serving using Phoenix - may be possible to generate a static site?

  • access to server side functionality via elixir - may be incorporated into Tau server?

  • Website style/functionality
  • Includes all sections

  • Includes all language translations - ability to switch languages via links

  • Styled like the online tutorial and Qt help section

  • Includes (semi-functional) theme switcher for light, dark, high contrast

  • Bootstrap webpage as proof of concept

  • Proof of concept pages/style tested, looks good

  • Need to implement Markdown rendering for tutorial and descriptions (maybe using something like phoenix_markdown with Earmark?)

  • @SunderB
    Copy link
    Contributor

    SunderB commented Sep 14, 2021

    Would having a Phoenix web server process in the background impact performance in any way?
    I'm assuming it would be managed by the boot daemon when the server starts like the other processes? Or would it be handled by the GUI?

    @ethancrawford
    Copy link
    Collaborator Author

    Table looks good! Just as long as we're aware that some of the choices I made like using a single TOML file per synth/function can be adjusted, using bootstrap was just a temporary hack for the POC, and Node.js is just a development dependency.
    Another thing I would also clarify is that AFAIK the live-reload feature is designed for the development environment. It may be possible to allow the same behaviour in production - this would certainly be useful for loading new content (potentially more than just custom synths? maybe even things like documentation for tools/plugins?) on-the-fly as you have mentioned 🙂

    (Re the markdown for the tutorials - as I mentioned above, if it was feasible, I'd probably convert them to TOML metadata just like the rest of the documentation, just so that we didn't have to have two separate methods for handling the conversion/parsing/displaying processes 🙂. That's just my view of it - and that's just assuming TOML/Phoenix is decided to be the way forward! 🤷‍♂️ ).

    Would having a Phoenix web server process in the background impact performance in any way?

    Unknown, so testing this will be useful. My initial instinct is that it's fine.

    I'm assuming it would be managed by the boot daemon when the server starts like the other processes? Or would it be handled by the GUI?

    Yes, the daemon. Sam has said elsewhere that he would see any Elixir-driven serving of html, whether through Phoenix or otherwise, to be built as an OTP app loaded as part of Tau. (Perhaps this all uses an Umbrella app). That way the daemon could just load a single umbrella app which then starts the individual pieces (Tau and whatever serves the HTML).

    Looking forward to Sam joining the conversation too. He's flat out for the next few weeks with travelling and generating much needed income, so won't be available until after that.

    @SunderB
    Copy link
    Contributor

    SunderB commented Sep 15, 2021

    Re the markdown for the tutorials - as I mentioned above, if it was feasible, I'd probably convert them to TOML metadata just like the rest of the documentation, just so that we didn't have to have two separate methods for handling the conversion/parsing/displaying processes

    The markdown would still have to be rendered at some point though? Unless there's some other markup we could use?

    @ethancrawford
    Copy link
    Collaborator Author

    The markdown would still have to be rendered at some point though?

    Technically, yes. It is more awkward to convert the markdown into structured data in a TOML file, unless maybe the 'structured data' is just a TOML multiline string that happens to contain the markdown verbatim. Which perhaps could be a little pointless.

    What I don't particularly much like about the tutorial being in markdown is that is forces the HTML into a certain structure, meaning that documentation designers who might want to adapt the tutorial content into their own project (a VS Code plugin for example) are forced to display the content exactly according to the HTML that the Markdown renders to - instead of having the freedom to structure the HTML how they like. The bonus of only storing the content/data of the tutorial in a portable form is that it separates it from the presentation format.

    The problem is that as I originally mentioned it's more involved to convert the markdown into a structured data format, since you have plain text with things like links interspersed through it.
    I haven't yet thought of a simple and effective way to represent the tutorials in TOML. It may well not be useful to do so - and may just be worth using Markdown. This just means we'd have to be ok with having two separate means for parsing/rendering content (one for structured data, one for rich text/mixed content), and be ok with forcing a pre-defined HTML structure on other projects that might adapt our tutorial.

    @ethancrawford
    Copy link
    Collaborator Author

    The more I think about it, the more I feel that having two distinct methods for encoding the documentation (markdown for rich text - Tutorial and Examples, TOML (or similar) for structured data - all other Help sections) makes sense. Attempting to encode rich text in TOML is probably more trouble than it is worth.
    Forcing a certain HTML structure on the Tutorial and Examples is probably not a big deal. At least external projects are going to be able to have a certain degree of control over the styling of the HTML.

    Just a thought, but I wonder about the idea of using intermediate ERB templates like I do for the TOML files, but instead of the templates generating TOML files for the Tutorial and Examples, they generate the Markdown...
    This does mean each Tutorial chapter page would have its own ERB template, instead of one template for many items like for the Synths, Fx, etc. But this way, since ERB is still Ruby, we can use Ruby gettext in the intermediate templates to extract the translatable text, exactly the way I have shown here for the TOML files. This would do away with things like Sam's custom scripts to extract the translatable text from the Markdown, as currently used in i18n-tool.rb. Does any of that make sense?

    @samaaron
    Copy link
    Collaborator

    One thing to consider is how it might be possible to use a new documentation system from a new language implementation. If, say, we were to re-implement things in Elixir, how might documentation be plugged in? This was the main motivation of suggesting something like toml to represent the structure and markdown as a way of representing the differences in text formatting. Personally I don't see any issue in throwing markdown strings into a toml document - although I'm totally happy to see other ideas explored.

    Using erb, or Ruby-specific things does throw some alarm bells up for me, but again, I'd be happy to see an overall plan of what you want to do so we can discuss it.

    I definitely think it makes sense to design the architecture, discuss and agree on it before any more coding is done just so we can all make sure we're happy with the direction :-)

    @ethancrawford
    Copy link
    Collaborator Author

    The only reason I've been working with the idea of ERB is that the Synth/FX/DSL metadata is currently in Ruby, and therefore it was trivial to access the metadata this way. The intention is not to leave the TOML generating code in Ruby indefinitely.

    Embedded templating scripts are nothing new; When we switch the DSL to something else (for which I understand Elixir is a good possibility) there are templating libraries available to use (Eex for example. I already show in the above code how to use it - the only difference if/when the entire DSL was switched over to Elixir would be that we would generate the TOML directly from Eex, as well as parsing this TOML with Eex to generate the HTML. Alternatively, even if the DSL ends up in Rust instead, there are templating script crates available there also, as I am confident there would be for other languages in turn).

    Markdown embedded in the TOML could work. It would be handy to do away with the custom markdown handling in i18n-tool.rb at least 🙂 I'd lean towards the idea I mention in the second paragraph of my previous reply, as using templates would allow us to include extraction of the translatable text in the process.

    @ethancrawford
    Copy link
    Collaborator Author

    ethancrawford commented Sep 17, 2021

    (This is how the tutorial markdown embedded in the ERB TOML template might look):

    <%=
    t_(<<~TEXT.chomp
     # a key to represent which chapter of the tutorial this is
     TEXT
    )
    %>
    [1]
    title = <%= t_("Welcome to Sonic Pi") %>
    content = '''
    # <%= t_("Welcome friend :-)") %>
    
    <%=
    t_(<<~TEXT.chomp
    Welcome to Sonic Pi. Hopefully you're as excited as I am to get started...
    TEXT
    )
    %>
    
    <%= t_("Some text with") %>[<%= t_("A link in it") %>](www.blahblah.com) <%= t_("embedded in TOML") %>
    '''
    

    @SunderB
    Copy link
    Contributor

    SunderB commented Sep 17, 2021

    (This is how the tutorial markdown embedded in the ERB TOML template might look):

    <%=
    t_(<<~TEXT.chomp
     # a key to represent which chapter of the tutorial this is
     TEXT
    )
    %>
    [1]
    title = <%= t_("Welcome to Sonic Pi") %>
    content = '''
    # <%= t_("Welcome friend :-)") %>
    
    <%=
    t_(<<~TEXT.chomp
    Welcome to Sonic Pi. Hopefully you're as excited as I am to get started...
    TEXT
    )
    %>
    
    <%= t_("Some text with") %>[<%= t_("A link in it") %>](www.blahblah.com) <%= t_("embedded in TOML") %>
    '''
    

    I get the approach, but a possible issue with this is that the order of parts of of sentence may differ between languages, so the positions of links relative to the other words may change.

    Also splitting parts of a sentence into different strings may make it harder to translate via weblate, as context may be lost? (I haven't used it before, so please correct me if I'm wrong on that)

    @ethancrawford
    Copy link
    Collaborator Author

    True - correct on both points. (Should have checked weblate first).
    So in this scheme, it would just look like this:

    content = '''
    ...other text
    
    <%= t_("Some text with [A link in it](www.blahblah.com) embedded in TOML") %>
    
    ...etc
    '''
    

    @ethancrawford
    Copy link
    Collaborator Author

    Looking forward to continuing the discussion about this when you are available @samaaron - please let me know if there's extra information you might need as well 👍

    @ethancrawford ethancrawford marked this pull request as ready for review September 23, 2021 14:10
    @ethancrawford
    Copy link
    Collaborator Author

    butterfingers 😂

    @ethancrawford ethancrawford marked this pull request as draft September 23, 2021 14:12
    @ethancrawford
    Copy link
    Collaborator Author

    I noticed the comments about removal of Node/NPM as dependencies in the Phoenix 1.6 RC 🙂

    @ethancrawford
    Copy link
    Collaborator Author

    @SunderB - are you up for a video chat about our PRs? I have sent a message on in_thread 🙂

    The translation pot file needs to contain references to files from *all* of
    the different documentation sections, to reduce duplication. To achieve this, we
    now process all of the collections of documentation data (synths/fx/lang/etc) as
    a single group.
    
    Several minor updates to the base templates have also been made.
    TODO: Add parsing code for TOML files, add live views etc
    Both the generating of the documentation TOML files and the Phoenix app's build
    process are now hooked into the pre-build process. The TOML templates have also
    been updated.
    This changes edits the styling of the view slightly with bootstrap and removes
    the default Phoenix styles. We also change the TOML documentation metadata
    structure slightly so that sliding information is included _within_ a synth/fx's
    data, not along-side it as an adjacent key/value.
    The file organisation in the web app has been changed to group things togather a
    little more logically. Also, the app is now using the documentation metadata
    generated by the Ruby server.
    The Pheonix web app has now had its Elixir and Node packages upgraded, to allow
    for easier development of some parts, such as HEex view templates.
    The variable tracking the side panel navigation headings has been renamed, to
    more accurately reflect what it represents.
    
    We now show a basic title or heading on each page in each of the main
    categories.
    
    Lastly, the 'Tutorial' and 'Examples' categories have been disabled as adding pages to
    those categories requires more work, which will not be done unless future
    discussions confirm this Phoenix app as the right approach.
    The utility functions were previously moved to a dedicated Paths module. This
    caused a conflict with the documentation rebuild code, but it has now been resolved.
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Labels
    None yet
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    None yet

    3 participants