3

テキストエリアから入力を受け取り、それをデータベースに入力する web.py アプリがあります。データベースから情報を取得してページに投稿できますが、NEWLINES はなくなりました。HTML に投稿するときに改行を保存するにはどうすればよいですか? データには含ま\r\nれていますが、HTML で NEWLINES としてレンダリングされません。何かご意見は?以下に小さな例を示します。

(2, u'Title', u'content here...hey\r\nthis\r\nhas\r\nbreaks in it....?', 
    datetime.datetime(2012, 7, 5, 21, 5, 14, 354516))

それがデータベースからの私のリターンです。\r\na を表すには が必要です。a<br />が 2 つある場合は<p>素晴らしいでしょう。どんな方向性でも大歓迎です。

また、これのためのライブラリはありますか?マークダウンとマークアップについて聞いたことがありますが、python 文字列から html データを投稿する方法の例が見つかりませんか?

4

4 に答える 4

11

これを行うには、主に 2 つの方法があります。最も簡単な方法は、入力したとおり<pre></pre>にフォーマットする出力をラップすることです。

または、文字が段落ではなく改行を表すため、 newlies を<br />( ではなく)に置き換えることができます。<p>

2 番目のオプションの場合、これは 1 つのアプローチです。

>>> s
'hello\nthere\r\nthis\n\ris a test'
>>> r = '<br />'
>>> s.replace('\r\n',r).replace('\n\r',r).replace('\r',r).replace('\n',r)
'hello<br />there<br />this<br />is a test'
>>> 

または3番目のオプション - 多くのテキスト入力ライブラリ/フォーマットの1つを使用し、それらを介してコンテンツをレンダリングすることです(他の人が述べたように-マークダウンなど)。

ただし、やりたいことが単純な置換だけである場合、それはやり過ぎです。

于 2012-07-07T10:26:47.877 に答える
6

改行が改行としてレンダリングされないのは、HTML で意図された動作です。あなたが望むのは、入力をテキスト段落に挿入する か解析し、それらを..<br>でラップすることです。<p></p>

私は両方の混合を行います:<br>単一の改行に使用し、<p>..</p>二重の改行に使用します。この解析は、データベースに保存するとき、または取得するときに行うことができます。

編集: 次の図を作成しました。パーサーを見る方法はたくさんあります。個人的には、それらをステート マシンの一種と考えたいと思います。これを実装するには、たとえばhttp://docs.python.org/library/stringio.htmlを使用して、ストリーミング方式で入力文字列を読み取る必要があります。

ここに画像の説明を入力 Edit2: 説明「プッシュダウン オートマトン」を「ステート マシン」に変更しました。プッシュダウン オートマトンは正確ですが、正確ではなく、グラフとうまく一致しません。2 つを混同しました。

Edit3: while ループ、switch case、および状態遷移の if ステートメントを使用して、コードでステート マシン パーサーを実装する方法に関する sudo コードを次に示します。

state = 'plainState'
streamer = get_stream_reader_from_input()
buffer = ''
while true {
  nextchar = streamer.readchar()
  if (nextchar == null) { //EOS
   print(buffer)
   exit
  }
  switch (state) {
    case('plainState') {
      if (nextchar == '\n') {
        state = 'singleBreakState' 
      }
      else if (nextchar == '\r') {
        state = 'CRState'
      }
      else {
        buffer += nextchar
      }
    }
    case('singleBreakState') {
      if (nextchar == '\n') {
        state = 'doubleBreakState' 
      }
      else if (nextchar == '\r') {
        state = 'CRState2'
      }
      else {
        state = 'plainState'
        buffer += '<br>' + nextchar
      }
    }
    //...
  }
}  
于 2012-07-06T05:27:27.280 に答える
3

解決策を考え出す前に、何が起こっているのかについての基本的な理解が必要です。問題を理解していない場合、「別のライブラリをスローする」アプローチはまったく機能しない (より良い) か、すぐに裏目に出てしまう (より悪い) かのいずれかです。

\n@MichelMüller は、HTML ソースの s がブラウザーでそのままレンダリングされないことを述べている点で正しいです。この動作の詳細な説明については、このチュートリアル(警告、HTML 2.0 について説明) を参照してください。さて、HTML に改行を入れるには、<br>;を使用します。新しい段落を入れるには、<p>.

これを達成するために多くのことを行うことができますが、解決しようとしている問題は何ですか? このユーザー投稿コンテンツは何ですか? 誰が提出するのですか?考慮すべき 2 つの側面は次のとおりです。

  1. フォーマット。公開サイトへのコメントか、ウェブサイトのスタッフが用意した投稿か、Stack Overflow のようなサイトの UGC か?
  2. セキュリティ。見知らぬ人によって投稿されたのか、それとも完全に信頼できるユーザーによって投稿されたのか、またはその中間に設定されたのか?

可能な解決策:

  • 最も直接的な方法はtext.replace('\r\n', '<br>')、テンプレート フォーマッタに出力する前に実行することです。{ text | safe }Jinja は<br>生成した s をエスケープしないため、テンプレートに a を配置しないと機能しません。ただし、テキスト自体は完全に信頼されるべきではないため<&(少なくとも)改行を置き換える前にエスケープする必要があります。

  • HTML エスケープを処理するアドホックではないアプローチについては、MarkupSafeを参照してください。ちなみに、ジンジャに採用されています。

  • 構造化されていないコンテンツ (つまり、ユーザーが投稿した YouTube のコメント) のフォーマットについてPottyMouthライブラリを参照してください。

  • コンテンツがより準備されている場合 (ブログ プラットフォームまたはスタック オーバーフローのようなサイトへの投稿)、@BernhardKircher の提案に従ってMarkdownを試してください。ある程度の学習曲線があるため、ユーザーが投稿の作成に時間を費やすことを厭わない場合に最適です。コア Markdown は HTML をエスケープしないため、パーサーを正しく構成することを忘れないでください。

  • スタッフが作成したコンテンツの場合は、Markdown またはより洗練されたものを使用できます。それは、スタッフのバックグラウンドによって大きく異なります。ここでは、エスケープされていない HTML は呪いではなく、祝福かもしれません。

于 2012-07-07T10:26:05.510 に答える
2

HTMLではないためhtmlとして表示されない挿入テキストを使用する代わりに(\r\nは「p」タグなどではありません)、マークダウンなどのフォーマット言語を使用できます(前述のとおり)。

それ以外の場合は、入力したテキストを手動で置換/解析する必要があります (マークダウンのような言語がこのために発明されているため、これは良い考えではないと思います)。

python-markdown2ように、マークダウン (データベースに保存するデータ) を html に変換するための優れた Python ライブラリがいくつかあります。

python-markdown リンクの例を参照してください。

>>> import markdown2
>>> markdown2.markdown("*boo!*")  # or use `html = markdown_path(PATH)`
u'<p><em>boo!</em></p>\n'

>>> markdowner = Markdown()
>>> markdowner.convert("*boo!*")
u'<p><em>boo!</em></p>\n'
>>> markdowner.convert("**boom!**")
u'<p><strong>boom!</strong></p>\n'

これにより、マークダウン構文 (または使用する形式) を使用してコンテンツを入力することが強制されます。これを簡単にするために、マークダウンを作成するwysiwyg-editorを使用できます (Stackoverflow のエディターなど)。Stackoverflow はwmdを使用していると思いますが、他にも多くのマークダウン wysiwyg エディターがあります。

wmd の例:

<html>
    <head>
        <title>WMD Example using jquery</title>
        <link rel="stylesheet" type="text/css" href="wmd.css"/>

        <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
        <script type="text/javascript" src="jquery.wmd.min.js"></script>
    </head>
    <body>
        <h1>WMD Example using jquery</h1>
        <div>
            <textarea id="notes"/>
        </div>

        <script type="text/javascript">
            $().ready(function() {
               $("#notes").wmd(); 
            });
        </script>
    </body>
</html>
于 2012-07-06T05:27:21.757 に答える