Convertire il codice HTML dell'elenco puntato in Markdown in AppleScript?

Oct 24 2020

Ho questo testo da manipolare in AppleScript (ad esempio il testo di una variabile):

Example note exported from Apple.

<ul>
  <li>Indent</li>
  <ul>
    <li>*Further* indent</li>
    <ul>
      <li>Even **further **indent. With a [link](https://duck.com).</li>
    </ul>
  </ul>
</ul>

End note.

Sto convertendo tutto in Markdown da HTML. Ho bisogno di ripulire questo bit rimanente di HTML che è l'elenco puntato, in modo che il risultato sia (con schede reali come spazio di rientro):

Example note exported from Apple.

- Indent
    - *Further* indent
        - Even **further **indent. With a [link](https://duck.com).

End note.

Deve essere in grado di soddisfare il rientro annidato a qualsiasi numero 'n' di livelli e possibilmente con del testo RTF all'interno degli elementi come questo esempio. Preferisco che l'output di Markdown utilizzi trattini e una tabulazione per il rientro.

Deve anche essere contenibile all'interno di applecript - nessun .pyfile esterno ecc. E non richiede l' homebrewinstallazione di uno strumento di terze parti.

Risposte

1 user3439894 Oct 24 2020 at 07:27

Il seguente codice AppleScript di esempio , come codificato, è destinato a funzionare con il codice HTML dell'elenco puntato come mostrato nell'OP , il che significa che ciò che viene passato nella variabile è solo il codice pertinente per definire l' elenco puntato e non altro codice HTML arbitrario .

Come codificato, produrrà l'output appropriato anche per le variazioni del codice HTML dell'elenco puntato , non solo per l' esempio specifico mostrato qui. Questo è stato testato su una varietà di altri esempi contenenti solo codice HTML con elenco puntato e produce l'output pertinente per esso come nell'esempio qui.

--  # Define exportedNote variable containing the bulleted list HTML code.

set exportedNote to "<ul>
  <li>Indent</li>
  <ul>
    <li>*Further* indent</li>
    <ul>
      <li>Even **further** indent. With a [link](https://duck.com).</li>
    </ul>
  </ul>
</ul>"

--  # Create an AppleScript list from the lines of bulleted list HTML code.

set exportedNoteList to paragraphs of exportedNote

--  # Process the list, acting only on items that contain "</li>" 
--  # as they are the only ones relevant to converting the 
--  # bulleted list HTML code to Markdown.

set tempList to {}
repeat with i from 1 to the number of items in exportedNoteList
    if item i of exportedNoteList contains "<li>" then
        set thisItem to item i of exportedNoteList
        set thisItem to findAndReplaceInText(thisItem, "</li>", "")
        set numberOfLeadingSpaces to ((offset of "<" in thisItem) - 1)
        if numberOfLeadingSpaces is less than 4 then
            set searchString to characters 1 thru numberOfLeadingSpaces of thisItem & "<li>" as text
            set thisItem to findAndReplaceInText(thisItem, searchString, "- ")
            set end of tempList to thisItem
        end if
        if numberOfLeadingSpaces is greater than 3 then
            set searchString to characters 1 thru numberOfLeadingSpaces of thisItem & "<li>" as text
            set thisItem to findAndReplaceInText(thisItem, searchString, "- ")
            set numberOfLeadingTabs to (numberOfLeadingSpaces / 2) as integer
            repeat with i from 1 to (numberOfLeadingTabs - 1)
                set thisItem to tab & thisItem
            end repeat
            set end of tempList to thisItem
        end if
    end if
end repeat

--  # Update the contents of the exportedNoteList
--  # list to contain only the relevant list items.

set exportedNoteList to tempList

--  # Convert the exportedNoteList list to text.

set AppleScript's text item delimiters to linefeed
set convertedNote to text items of exportedNoteList
set convertedNote to convertedNote as text
set AppleScript's text item delimiters to {}

--  # 'return' is only used to show its value in Script Editor. Use
--  # the convertedNote variable as needed in the working code.

return convertedNote


--  # Handler(s)

--  # Note: Handlers may be placed as one chooses as appropriate.
--  # My preference is at the bottom of the rest of the code.

on findAndReplaceInText(theText, theSearchString, theReplacementString)
    set AppleScript's text item delimiters to theSearchString
    set theTextItems to every text item of theText
    set AppleScript's text item delimiters to theReplacementString
    set theText to theTextItems as string
    set AppleScript's text item delimiters to ""
    return theText
end findAndReplaceInText

Risultato:

"- Indent
    - *Further* indent
        - Even **further** indent. With a [link](https://duck.com)."

Che viene visualizzato come segue in un browser su questo sito web:

  • Rientro
    • Ulteriore trattino
ἐλευθερία Oct 24 2020 at 21:39

Risponderò anche a questa domanda con un metodo alternativo che ho elaborato:

set exportedNote to "Example note exported from Apple.

<ul>
  <li>Indent</li>
  <ul>
    <li>*Further* indent</li>
    <ul>
      <li>Even **further **indent. With a [link](https://duck.com).</li>
    </ul>
  </ul>
</ul>

End note."

set deleteHTMLline to {"<ul>"}
set exportedNote to deleteLinesFromText(exportedNote, deleteHTMLline) of me as text
set deleteHTMLline to {"</ul>"}
set exportedNote to deleteLinesFromText(exportedNote, deleteHTMLline) of me as text

set exportedNote to replace_chars(exportedNote, "      <li>", tab & tab & "- ") of me as text
set exportedNote to replace_chars(exportedNote, "    <li>", tab & "- ") of me as text
set exportedNote to replace_chars(exportedNote, "  <li>", "- ") of me as text
set exportedNote to replace_chars(exportedNote, "</li>", "") of me as text

return exportedNote

on replace_chars(this_text, search_string, replacement_string)
    set AppleScript's text item delimiters to the search_string
    set the item_list to every text item of this_text
    set AppleScript's text item delimiters to the replacement_string
    set this_text to the item_list as string
    set AppleScript's text item delimiters to {""}
    return this_text
end replace_chars

on deleteLinesFromText(theText, deletePhrase)
    set newText to ""
    try
        set textList to paragraphs of theText
        repeat with i from 1 to count of textList
            set thisLine to item i of textList
            if thisLine does not contain deletePhrase then
                set newText to newText & thisLine & return
            end if
        end repeat
        if newText is not "" then set newText to text 1 thru -2 of newText
    on error
        set newText to theText
    end try
    return newText
end deleteLinesFromText

Risultato:

Example note exported from Apple.

- Indent
    - *Further* indent
        - Even **further **indent. With a [link](https://duck.com).

End note.

Appunti:

Analogamente alla risposta principale, se desideri convertire ulteriori livelli di rientro, dovrai aggiungere righe extra.

Questo codice di esempio converte solo tre livelli. Per aggiungerne un quarto, puoi aggiungere nella parte superiore della set exportedNote to replace_charssezione:

set exportedNote to replace_chars(exportedNote, "        <li>", tab & tab & tab & "- ") of me as text

Aggiungi livelli più profondi in alto scendendo in ordine cronologico con altri due spazi prima di ciascuno <li>e uno in più tab &.

Se qualcuno ha il codice per poter convertire un nnumero qualsiasi di livelli di rientro, si prega di intervenire o inviare modifiche.