日本語のキレイな改行(Budou - CJK Line Break Organizer)

すっかり放置してしまいましたので気になったトピックをメモ。

github.com

話題になってた「日本語(中国語・韓国語も)を綺麗に改行出来るライブラリ」。

導入したいケースが多いそうなので試して見たら、裏側が思ったよりも力技。

  1. GoogleのCloud Natural Language APIを使って、構文解析
  2. 文節単位でブロックで囲う
  3. リサイズの度に↑

おぉ・・いつかスタンドアロン化されることに期待。

reveal.js+Markdown

LT練習することになりMarkdownでアウトライン書き終えたところで力尽きたので、センターに「ばーんばーん」でいいからスライドにならないかなと思って探してみた。

reveal.js

HTMLベースのプレゼンテーションフレームワークgithub.com

Setup

フルセットアップ(おすすめ)する。

# クローンして
$ git clone git@github.com:hakimel/reveal.js.git

# nodejs環境を構築
$ npm install

# サーバ起動
$ grunt serve

# ローカルサーバが起動してついでにブラウザも立ち上がる

これでサンプルのスライドが表示されると思います。

基本的にはスペースキーでパンパン次のスライドに進めますが、Markdownで記述出来るようにしてついでに別ファイル化するために index.html を変更します。

index.html オリジナル

<div class="reveal">
  <div class="slides">
    <!-- ここにスライドスライドの内容が書かれている -->
  </div>
</div>

index.html 変更後

<div class="reveal">
  <div class="slides">
    <!-- 外部ファイル化するために書き換える -->
    <section data-markdown="md/index.md"
          data-separator="---$"
          data-separator-vertical=">>>$">
      <script type="text/template">
      </script>
    </section>
  </div>
</div>

md/index.md

# reveal.js 
***
試してみた

>>>
補足情報

---
*あった方が*<!-- .element: class="fragment" -->
*メリハリが出る*<!-- .element: class="fragment" -->
*こういう機能とか*<!-- .element: class="fragment" -->

---
**打ち消しとか**<!-- .element: class="strike fragment" -->

その他色々なオプション

実際のデモを触ってもらうのが一番わかりやすいと思います。
Markdownで箇条書きしたものを話の流れに合わせて演出変えた等するだけで十分な見栄えになりました。

個人的に特に気に入ってる機能

Sキーで開くSpeakerViewは元のウィンドウと同期して次のスライドや経過時刻が見れるのでLTなどで便利そうです。

おまけ

スライド時に音。

<audio data-autoplay src="sound.mp3"></audio>

RailsとWordPressの共存(PassengerのOn/Off)

Rails環境のpublic/以下にWordPressをインストールしたら躓いた。

こんな感じの構成
http://example.com/Railsアプリ
http://example.com/wpWordPress

調べてみたらPassengerの有効範囲が広すぎて.htaccessの挙動に影響が出ていたみたい。   (DirectoryIndexとかRewriteRuleが動かない)

.htaccessに1行入れるだけだった!

PassengerEnabled off

Xcodeのインストールが完了しない

Xcodeのアップデートは面倒ですね。

インストールが「残り〜分」と出てからで小一時間進まないことがあります。
結局どれが功を奏したかわかりませんが、その時にやった内容メモ。

1. セーフモードで起動

Shiftを押しながらMacを起動してセーフモード起動をします。
キャッシュファイルの削除等をしてくれるみたい。

2. iTunesHelper

Xcodeインストール時にiTunesが起動していたら終了するか聴いてくれますが、iTunesHelperは生きてるのでここで詰まるみたいです。
アクティビティモニタから叩き落として数分放置したらプログレスバーが動き始めました。

Unity 0.0f ←このf?

Unity触ってたら出てきた変な接尾語。

float(32bit浮動小数点数)のf。

タイプ 説明 表記例
int 符号付き 32bit整数 0
float 符号付き32bit浮動小数点数 0.0f
double 符号付き64bit浮動小数点数 0.0d
decimal 符号付き128bit浮動小数点数 0.0m

GASでSpreadsheetの範囲取得時のTips

しばらくGoogleAppScript触ってました。

複数行を取得する際に馬鹿正直にループしたらパフォーマンスがひどかったので調べたら範囲.getValues()で配列として取得するのがいいそうな。

A B
1 アイテムA ..
2 アイテムB ..
3 アイテムC ..
4 アイテムD ..
5 アイテムE ..
# これを実行すると
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getRange(1, 1, 5, 1).getValues();
Logger.log(values);

#こんな2次元配列帰ってくる
# ⇒ [[アイテムA], [アイテムB], [アイテムC], [アイテムD], [アイテムE]]

# 1次元配列を期待していた
# ⇒ [アイテムA, アイテムB, アイテムC, アイテムD, アイテムE]

仕様的に↓こんな行列も取得できるためそうならざるを得ないんだろうけど、1列で良かった場合は処理が面倒。

A B
1
2
3
4
5

なので、GASでUnderscoreを使って1次元化します。

ライブラリの読み込み

Scriptエディタの「リソース > ライブラリ > ライブラリを検索」に下記をいれます。
MGwgKN2Th03tJ5OdmlzB8KPxhMjh3Sh48 https://script.google.com/macros/library/versions/d/MGwgKN2Th03tJ5OdmlzB8KPxhMjh3Sh48

Underscoreがリストに追加されるので利用するバージョン(2016/04/07時点で24)を選択。

var _ = Underscore.load();
var sheet = SpreadsheetApp.getActiveSheet();
var values = sheet.getRange(1, 1, 5, 1).getValues();
values = _.flatten(values);
Logger.log(values);

# やったね
# ⇒ [アイテムA, アイテムB, アイテムC, アイテムD, アイテムE]

GoogleTagManagerでソーシャルインタラクション

前々回に試したかったGoogleTagManager(以下GTM)でのソーシャルインタラクションの設定方法。 (わざわざHerokuアップしなくてもローカルでも確認できた・・)

Universal Analyticsになっても、GTMを使っても、ソーシャルインタラクションの取得には一手間必要だそうです。

HerokuでMiddleman - hhmmm

1. ページにTwitter, Facebookの埋め込みScript

公式の埋め込み用スクリプトを共通化してまとめておきます。

<!-- twitter script -->
<script>
window.twttr = (function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0],
    t = window.twttr || {};
  if (d.getElementById(id)) return;
  js = d.createElement(s);
  js.id = id;
  js.src = "https://platform.twitter.com/widgets.js";
  fjs.parentNode.insertBefore(js, fjs);
 
  t._e = [];
  t.ready = function(f) {
    t._e.push(f);
  };
 
  return t;
}(document, "script", "twitter-wjs"));
</script>

<!-- facebook script -->
<div id="fb-root"></div>
<script>(function(d, s, id) {
  var js, fjs = d.getElementsByTagName(s)[0];
  if (d.getElementById(id)) return;
  js = d.createElement(s); js.id = id;
  js.src = "//connect.facebook.net/ja_JP/sdk.js#xfbml=1&version=v2.5&appId=323729011016547";
  fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));</script>

コードの埋め込み場所はGTMの埋め込みコードより手前です。

2. ページにボタンの設置

<!-- Twitter -->
<a href="https://twitter.com/share" class="twitter-share-button" data-url="http://example.com" data-text="ごにょごにょ" data-lang="ja" data-count="none">ツイート</a>

<!-- Facebook -->
<div class="fb-like" data-href="http://example.com" data-layout="standard" data-action="like" data-show-faces="true" data-share="true"></div>

ボタンは設置したい箇所に、好きなだけ。

3. GTMの設定

ここからはGTM(v2)画面です。

Tags

f:id:hhmmm:20160316162643p:plain

Triggers

f:id:hhmmm:20160316162747p:plain

Variables

f:id:hhmmm:20160316162753p:plain

3-1. Variablesの設定

データレイヤ変数を追加

socialAction

f:id:hhmmm:20160316164202p:plain

socialNetwork

f:id:hhmmm:20160316164306p:plain

socialTarget

f:id:hhmmm:20160316164317p:plain

UA-ID

管理しやすいようにGoogle AnalyticsプロパティIDを追加 f:id:hhmmm:20160316164538p:plain

3-2. Triggersの設定

socialEvent

f:id:hhmmm:20160316164754p:plain

Window Loaded

f:id:hhmmm:20160316164823p:plain

3-3. Tagsの設定

socialEvent Listener

さきほど追加したデータレイヤ変数とGoogle AnalyticsプロパティIDを設定します。 f:id:hhmmm:20160316165440p:plain

SocialInteraction code

f:id:hhmmm:20160316170127p:plain

コードの中身

<script>
$(function(){
  // Twitter
  function clickEventToAnalytics (intentEvent) {
    if (!intentEvent) return;
    var socialNetwork = 'twitter';
    var socialAction = intentEvent.region;
    var socialTarget = $(intentEvent.target).attr('data-url') ? $(intentEvent.target).attr('data-url') : window.location.href;
    dataLayer.push({
     'event': 'socialEvent',
     'socialNetwork': socialNetwork,
     'socialAction': socialAction,
     'socialTarget': socialTarget
    });
  }
  function tweetIntentToAnalytics (intentEvent) {
    if (!intentEvent) return;
    var socialNetwork = 'twitter';
    var socialAction = 'tweet';
    var socialTarget = $(intentEvent.target).attr('data-url') ? $(intentEvent.target).attr('data-url') : window.location.href;
    dataLayer.push({
     'event': 'socialEvent',
     'socialNetwork': socialNetwork,
     'socialAction': socialAction,
     'socialTarget': socialTarget
    });
  }
  
  if("undefined" != typeof twttr){
    twttr.ready(function (twttr) {
      twttr.events.bind('click', clickEventToAnalytics);
      twttr.events.bind('tweet', tweetIntentToAnalytics);
    });
  };

  // Facebook
  window.fbAsyncInit = function() {
    FB.Event.subscribe('edge.create', function(targetUrl) {
      var socialNetwork = 'facebook';
      var socialAction = 'like';
      var socialTarget = targetUrl;
      dataLayer.push({
       'event': 'socialEvent',
       'socialNetwork': socialNetwork,
       'socialAction': socialAction,
       'socialTarget': socialTarget
      });
    });
    FB.Event.subscribe('edge.remove', function(targetUrl) {
      var socialNetwork = 'facebook';
      var socialAction = 'unlike';
      var socialTarget = targetUrl;
      dataLayer.push({
       'event': 'socialEvent',
       'socialNetwork': socialNetwork,
       'socialAction': socialAction,
       'socialTarget': socialTarget
      });
    });
  };
});
</script>

発火タイミングにWindow Loadedがないと、たまに発火しない時があったためおまじないの様に。

Universal Analytics

Google Analyticsの普通のPageViewです。 f:id:hhmmm:20160316170805p:plain

4. ページにGTMスニペットを追加

<body>
<!-- ここに 1. SNSボタンのScript -->
<!-- Google Tag Manager -->
<noscript><iframe src="//www.googletagmanager.com/ns.html?id=GTM-XXXXXX"
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
'//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','GTM-XXXXXX');</script>
<!-- End Google Tag Manager -->
</body>

画像いっぱい!